├── .github └── workflows │ ├── build-and-test.yml │ └── deploy-examples.yml ├── .gitignore ├── .idea └── .gitignore ├── LICENSE ├── README.md ├── elm.json ├── examples ├── ModelViewer.elm ├── README.md ├── Shaders.elm ├── Suzanne.elm ├── elm.json ├── meshes │ ├── elmLogo.obj │ ├── suzanne.obj │ └── suzanneNoUV.obj └── textures │ ├── chavant.jpg │ ├── elmLogoDiffuse.png │ └── elmLogoNorm.png ├── package-lock.json ├── package.json ├── src ├── OBJ.elm └── OBJ │ ├── Assembler.elm │ ├── InternalTypes.elm │ ├── Parser.elm │ └── Types.elm └── tests ├── ObjData.elm └── ParserTests.elm /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: Build & Test 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | - run: npm install 20 | 21 | - name: Test 22 | run: npm run test 23 | -------------------------------------------------------------------------------- /.github/workflows/deploy-examples.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Deploy examples 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | 10 | jobs: 11 | deploy: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - name: Use Node.js 14 19 | uses: actions/setup-node@v1 20 | with: 21 | node-version: 14.x 22 | 23 | - name: Install project packages 24 | run: npm install 25 | 26 | - name: Build Examples 27 | run: npm run build-examples 28 | 29 | - name: Deploy 30 | uses: peaceiris/actions-gh-pages@v3 31 | with: 32 | github_token: ${{ secrets.GITHUB_TOKEN }} 33 | publish_dir: ./dist 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | elm-stuff/ 2 | node_modules/ 3 | dist/ 4 | 5 | # Jetbrains 6 | .idea/ 7 | examples/*.html 8 | *.log 9 | 10 | ~* 11 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Jetbrains 2 | .idea/ 3 | 4 | *.tmp 5 | *.so 6 | 7 | # Elm 8 | elm-stuff 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Florian Zinggeler 4 | 2019 Nick Boultbee 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ⚠️ **This repo is now deprecated, in favour of the excellent [elm-obj-file](https://github.com/w0rm/elm-obj-file) which works well with [Elm 3D Scene](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest)** 2 | 3 | ---- 4 | 5 | elm-obj-loader 6 | ============== 7 | 8 | ![Node.js CI](https://github.com/declension/elm-obj-loader/workflows/Node.js%20CI/badge.svg) 9 | 10 | This is an Elm library for importing simple [Wavefront `.obj`][objSpecs] files into your WebGL application. 11 | 12 | It is currently Elm 0.19, though [the previous incarnation](https://package.elm-lang.org/packages/Zinggi/elm-obj-loader/) works for 0.18. 13 | 14 | 15 | Examples 16 | -------- 17 | * [Model viewer][modelViewer] 18 | * [Suzanne from Blender][suzanne] 19 | 20 | See the [demo source](/examples). 21 | 22 | 23 | Usage 24 | ----- 25 | * Export / convert your model from Blender or other 3D content creation tool as an `.obj` file. 26 | * The default export options from Blender work fine. 27 | * Make sure you keep _Write Normals_ selected. 28 | 29 | 30 | Limitations 31 | ----------- 32 | 33 | Completely supported face types are those with vertex position, normals and optionally vertex texture coordinates. (`v`, `vn`, `vt`) 34 | Only a small subset of the specification is supported though - specifically: 35 | 36 | * Your model needs vertex normals (`vn`). 37 | * Smooth groups are ignored (`s n`). 38 | * Only tris and quads are supported. (Tris might load slightly faster) 39 | * No free-form curves / surfaces. 40 | * No material library ([mtllib](http://people.sc.fsu.edu/~jburkardt/data/mtl/mtl.html)) support. 41 | * No negative indexing. 42 | 43 | 44 | [suzanne]: https://declension.github.io/elm-obj-loader/suzanne.html 45 | [modelViewer]: https://declension.github.io/elm-obj-loader/model-viewer.html 46 | [objSpecs]: http://www.martinreddy.net/gfx/3d/OBJ.spec 47 | -------------------------------------------------------------------------------- /elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "package", 3 | "name": "declension/elm-obj-loader", 4 | "summary": "Load Wavefront .obj files in your WebGL scene.", 5 | "license": "MIT", 6 | "version": "1.0.1", 7 | "exposed-modules": [ 8 | "OBJ", 9 | "OBJ.Types" 10 | ], 11 | "elm-version": "0.19.0 <= v < 0.20.0", 12 | "dependencies": { 13 | "andre-dietrich/parser-combinators": "3.1.1 <= v < 4.0.0", 14 | "elm/core": "1.0.2 <= v < 2.0.0", 15 | "elm/http": "1.0.0 <= v < 2.0.0", 16 | "elm/json": "1.1.3 <= v < 2.0.0", 17 | "elm/regex": "1.0.0 <= v < 2.0.0", 18 | "elm-explorations/linear-algebra": "1.0.3 <= v < 2.0.0" 19 | }, 20 | "test-dependencies": { 21 | "elm-explorations/test": "1.2.1 <= v < 2.0.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/ModelViewer.elm: -------------------------------------------------------------------------------- 1 | module ModelViewer exposing (CameraInfo, Model, Msg(..), Size, decodeMouse, getCamera, getDelta, initCmd, initModel, loadModel, loadTexture, main, models, onZoom, renderCullFace, renderModel, selectModel, subscriptions, update, view) 2 | 3 | import Browser exposing (Document) 4 | import Browser.Dom 5 | import Browser.Events exposing (onAnimationFrameDelta, onMouseDown, onMouseMove, onMouseUp, onResize) 6 | import Dict exposing (Dict) 7 | import Html exposing (Html, div, main_, text) 8 | import Html.Attributes as Attr exposing (style) 9 | import Html.Events exposing (on, onCheck, onInput) 10 | import Json.Decode as JD exposing (int) 11 | import Math.Matrix4 as M4 exposing (Mat4) 12 | import Math.Vector2 as Vec2 exposing (Vec2, vec2) 13 | import Math.Vector3 exposing (Vec3, vec3) 14 | import OBJ 15 | import OBJ.Types exposing (Mesh(..), ObjFile) 16 | import Shaders 17 | import String exposing (fromInt) 18 | import Task 19 | import WebGL as GL 20 | import WebGL.Settings exposing (cullFace, front) 21 | import WebGL.Settings.DepthTest as DepthTest 22 | import WebGL.Texture exposing (Error(..), Texture) 23 | 24 | 25 | main : Program () Model Msg 26 | main = 27 | Browser.document 28 | { init = always ( initModel, initCmd ) 29 | , view = view 30 | , subscriptions = subscriptions 31 | , update = update 32 | } 33 | 34 | 35 | 36 | -- MODEL 37 | 38 | 39 | type alias Model = 40 | { time : Float 41 | , mesh : Result String ObjFile 42 | , currentModel : String 43 | , zoom : Float 44 | , diffText : Result String Texture 45 | , normText : Result String Texture 46 | , isDown : Bool 47 | , lastMousePos : Vec2 48 | , mouseDelta : Vec2 49 | , windowSize : Size 50 | , withTangent : Bool 51 | } 52 | 53 | 54 | initModel : Model 55 | initModel = 56 | { mesh = Err "loading ..." 57 | , currentModel = "meshes/elmLogo.obj" 58 | , time = 0 59 | , zoom = 3.5 60 | , diffText = Err "Loading texture..." 61 | , normText = Err "Loading texture..." 62 | , isDown = False 63 | , lastMousePos = vec2 0 0 64 | , mouseDelta = vec2 0 (pi / 2) 65 | , windowSize = Size 0 0 66 | , withTangent = True 67 | } 68 | 69 | 70 | models : List String 71 | models = 72 | [ "meshes/elmLogo.obj" 73 | , "meshes/suzanneNoUV.obj" 74 | ] 75 | 76 | 77 | initCmd : Cmd Msg 78 | initCmd = 79 | Cmd.batch 80 | [ loadModel True "meshes/elmLogo.obj" 81 | , loadTexture "textures/elmLogoDiffuse.png" DiffTextureLoaded 82 | , loadTexture "textures/elmLogoNorm.png" NormTextureLoaded 83 | , Task.perform 84 | (\{ viewport } -> 85 | ResizeWindow (round viewport.width) (round viewport.height) 86 | ) 87 | Browser.Dom.getViewport 88 | ] 89 | 90 | 91 | loadModel : Bool -> String -> Cmd Msg 92 | loadModel withTangents url = 93 | OBJ.loadObjFileWith { withTangents = withTangents } url (LoadObj url) 94 | 95 | 96 | 97 | -- UPDATE 98 | 99 | 100 | type alias Size = 101 | { width : Int, height : Int } 102 | 103 | 104 | type Msg 105 | = Tick Float 106 | | LoadObj String (Result String (Dict String (Dict String Mesh))) 107 | | Zoom Float 108 | | MouseMove Int Int 109 | | MouseDown Int Int 110 | | MouseUp 111 | | DiffTextureLoaded (Result String Texture) 112 | | NormTextureLoaded (Result String Texture) 113 | | ResizeWindow Int Int 114 | | SelectMesh String 115 | | SetUseTangent Bool 116 | 117 | 118 | type alias CameraInfo = 119 | { projection : Mat4, view : Mat4, viewProjection : Mat4, position : Vec3 } 120 | 121 | 122 | update : Msg -> Model -> ( Model, Cmd Msg ) 123 | update msg model = 124 | case msg of 125 | Tick dt -> 126 | ( { model | time = model.time + dt / 1000 }, Cmd.none ) 127 | 128 | Zoom dy -> 129 | ( { model | zoom = max 1 (model.zoom + dy / 10) }, Cmd.none ) 130 | 131 | SelectMesh url -> 132 | ( model, loadModel model.withTangent url ) 133 | 134 | SetUseTangent t -> 135 | ( { model | withTangent = t }, loadModel t model.currentModel ) 136 | 137 | LoadObj url mesh -> 138 | ( { model | mesh = mesh, currentModel = url }, Cmd.none ) 139 | 140 | DiffTextureLoaded t -> 141 | ( { model | diffText = t }, Cmd.none ) 142 | 143 | NormTextureLoaded t -> 144 | ( { model | normText = t }, Cmd.none ) 145 | 146 | MouseDown x y -> 147 | ( { model | isDown = True, lastMousePos = vec2 (toFloat x) (toFloat y) }, Cmd.none ) 148 | 149 | MouseUp -> 150 | ( { model | isDown = False }, Cmd.none ) 151 | 152 | MouseMove x y -> 153 | let 154 | pos = 155 | vec2 (toFloat x) (toFloat y) 156 | in 157 | ( { model | mouseDelta = getDelta pos model.lastMousePos model.mouseDelta, lastMousePos = pos }, Cmd.none ) 158 | 159 | ResizeWindow x y -> 160 | ( { model | windowSize = { width = x, height = y } }, Cmd.none ) 161 | 162 | 163 | 164 | -- VIEW / RENDER 165 | 166 | 167 | renderModel : Model -> Texture -> Texture -> Mesh -> GL.Entity 168 | renderModel model textureDiff textureNorm mesh = 169 | let 170 | camera = 171 | getCamera model 172 | 173 | modelM = 174 | M4.makeTranslate (vec3 -1 0 0) 175 | 176 | theta = 177 | -1.75 * model.time 178 | 179 | lightPos = 180 | vec3 (0.5 * cos theta) (1 + 0.5 * sin theta) 0.5 181 | 182 | uniforms = 183 | { camera = camera 184 | , mvMat = M4.mul camera.view modelM 185 | , modelViewProjectionMatrix = M4.mul camera.viewProjection modelM 186 | , modelMatrix = modelM 187 | , viewPosition = camera.position 188 | , textureDiff = textureDiff 189 | , textureNorm = textureNorm 190 | , lightPosition = lightPos 191 | } 192 | in 193 | case mesh of 194 | WithoutTexture { vertices, indices } -> 195 | renderCullFace Shaders.simpleVert Shaders.simpleFrag (GL.indexedTriangles vertices indices) uniforms 196 | 197 | WithTexture { vertices, indices } -> 198 | renderCullFace Shaders.noNormalVert Shaders.noNormalFrag (GL.indexedTriangles vertices indices) uniforms 199 | 200 | WithTextureAndTangent { vertices, indices } -> 201 | renderCullFace Shaders.normalVert Shaders.normalFrag (GL.indexedTriangles vertices indices) uniforms 202 | 203 | 204 | getCamera : Model -> CameraInfo 205 | getCamera { mouseDelta, zoom, windowSize } = 206 | let 207 | ( mx, my ) = 208 | ( Vec2.getX mouseDelta, Vec2.getY mouseDelta ) 209 | 210 | aspect = 211 | toFloat windowSize.width / toFloat windowSize.height 212 | 213 | proj = 214 | M4.makePerspective 45 aspect 0.01 10000 215 | 216 | position = 217 | vec3 (zoom * sin -mx * sin my) (-zoom * cos my + 1) (zoom * cos -mx * sin my) 218 | 219 | view_ = 220 | M4.makeLookAt position (vec3 0 1 0) (vec3 0 1 0) 221 | in 222 | { projection = proj, view = view_, viewProjection = M4.mul proj view_, position = position } 223 | 224 | 225 | view : Model -> Document Msg 226 | view model = 227 | { title = "OBJ Model Viewer - elm-obj-loader" 228 | , body = 229 | [ main_ [ style "width" "100vw", style "height" "100vh" ] 230 | [ selectModel model 231 | , case ( model.mesh, model.diffText, model.normText ) of 232 | ( Ok m, Ok td, Ok tn ) -> 233 | GL.toHtmlWith [ GL.antialias, GL.depth 1 ] 234 | [ onZoom 235 | , Attr.width model.windowSize.width 236 | , Attr.height model.windowSize.height 237 | , Attr.style "position" "absolute" 238 | ] 239 | (Dict.values m 240 | |> List.concatMap Dict.values 241 | |> List.map (renderModel model td tn) 242 | ) 243 | 244 | ( Err m, _, _ ) -> 245 | Html.pre [] [ Html.text <| "ERROR with mesh: " ++ m ] 246 | 247 | _ -> 248 | Html.pre [] [ Html.text <| "Non-mesh error." ] 249 | ] 250 | ] 251 | } 252 | 253 | 254 | selectModel : Model -> Html Msg 255 | selectModel model = 256 | div [ Attr.style "position" "absolute", Attr.style "z-index" "2", Attr.style "backgroundColor" "white" ] 257 | ([ Html.select [ onInput SelectMesh, Attr.value model.currentModel ] 258 | (List.map (\t -> Html.option [ Attr.value t ] [ text t ]) models) 259 | ] 260 | ++ (if String.startsWith "meshes/elmLogo" model.currentModel then 261 | [ text "\twith normal map: " 262 | , Html.input [ Attr.type_ "checkbox", onCheck SetUseTangent, Attr.checked model.withTangent ] [] 263 | ] 264 | 265 | else 266 | [] 267 | ) 268 | ) 269 | 270 | 271 | 272 | -- SUBS 273 | 274 | 275 | subscriptions : Model -> Sub Msg 276 | subscriptions model = 277 | Sub.batch 278 | ((if model.isDown then 279 | [ onMouseMove (decodeMouse MouseMove) ] 280 | 281 | else 282 | [] 283 | ) 284 | ++ [ onAnimationFrameDelta Tick 285 | , onMouseUp (JD.succeed MouseUp) 286 | , onMouseDown (decodeMouse MouseDown) 287 | , onResize ResizeWindow 288 | ] 289 | ) 290 | 291 | 292 | 293 | -- HELPERS 294 | 295 | 296 | decodeMouse : (Int -> Int -> Msg) -> JD.Decoder Msg 297 | decodeMouse mapper = 298 | JD.map2 mapper 299 | (JD.field "clientX" int) 300 | (JD.field "clientY" int) 301 | 302 | 303 | onZoom : Html.Attribute Msg 304 | onZoom = 305 | on "wheel" (JD.map Zoom (JD.field "deltaY" JD.float)) 306 | 307 | 308 | getDelta : Vec2 -> Vec2 -> Vec2 -> Vec2 309 | getDelta curr lastP delta = 310 | vec2 ((Vec2.getX curr - Vec2.getX lastP) / 100 + Vec2.getX delta) 311 | ((Vec2.getY curr - Vec2.getY lastP) / 100 + Vec2.getY delta |> clamp 0.01 pi) 312 | 313 | 314 | loadTexture : String -> (Result String Texture -> msg) -> Cmd msg 315 | loadTexture url toMsg = 316 | WebGL.Texture.load url 317 | |> Task.attempt 318 | (\r -> 319 | case r of 320 | Ok t -> 321 | toMsg (Ok t) 322 | 323 | Err LoadError -> 324 | toMsg (Err "Failed to load texture") 325 | 326 | Err (SizeError w h) -> 327 | toMsg (Err ("Invalid texture size: " ++ fromInt w ++ " x " ++ fromInt h)) 328 | ) 329 | 330 | 331 | renderCullFace : GL.Shader a u v -> GL.Shader {} u v -> GL.Mesh a -> u -> GL.Entity 332 | renderCullFace = 333 | GL.entityWith [ DepthTest.default, cullFace front ] 334 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Running 2 | Due to [a bug in elm reactor](https://github.com/elm-lang/elm-reactor/issues/217), the obj file will be served as an html page instead of `plain/text`. This screws up the parsing. 3 | 4 | Using another file server works, e.g. 5 | using [elm-live](https://github.com/tomekwi/elm-live) or `python -m http.server` 6 | 7 | # Acknowledgements 8 | 9 | Brick textures were taken from: http://www.textures.com/ 10 | -------------------------------------------------------------------------------- /examples/Shaders.elm: -------------------------------------------------------------------------------- 1 | module Shaders exposing (..) 2 | 3 | import WebGL 4 | 5 | 6 | {-| This shader uses Spherical Environment Mapping (SEM). 7 | Here are some relevant links: 8 | 9 | - [very cool demo](https://www.clicktorelease.com/code/spherical-normal-mapping/#) 10 | - 11 | - 12 | 13 | -} 14 | reflectionVert = 15 | [glsl| 16 | 17 | attribute vec3 position; 18 | attribute vec3 normal; 19 | uniform mat4 mvMat; 20 | uniform mat4 camera; 21 | varying vec3 vNormal; 22 | 23 | void main() 24 | { 25 | vec4 vertex4 = mvMat * vec4(position, 1.0); 26 | vNormal = vec3(mvMat * vec4(normal, 0.0)); 27 | vec3 nm_z = normalize(vec3(vertex4)); 28 | vec3 nm_x = cross(nm_z, vec3(0.0, 1.0, 0.0)); 29 | vec3 nm_y = cross(nm_x, nm_z); 30 | vNormal = vec3(dot(vNormal, nm_x), dot(vNormal, nm_y), dot(vNormal, nm_z)); 31 | gl_Position = camera * vertex4; 32 | } 33 | 34 | |] 35 | 36 | 37 | reflectionFrag = 38 | [glsl| 39 | precision mediump float; 40 | 41 | uniform sampler2D texture; 42 | 43 | varying vec3 vNormal; 44 | 45 | void main() 46 | { 47 | vec2 texCoord = vec2(0.5 * vNormal.x + 0.5, - 0.5 * vNormal.y - 0.5); 48 | vec4 fragColor = texture2D(texture, texCoord); 49 | fragColor.a = 1.0; 50 | 51 | gl_FragColor = fragColor; 52 | } 53 | 54 | |] 55 | 56 | 57 | {-| normal mapping according to: 58 | 59 | -} 60 | normalVert = 61 | [glsl| 62 | attribute vec3 position; 63 | attribute vec3 normal; 64 | attribute vec2 texCoord; 65 | attribute vec4 tangent; 66 | 67 | varying vec2 vTexCoord; 68 | varying vec3 vLightDirection; 69 | varying vec3 vViewDirection; 70 | 71 | 72 | uniform mat4 modelViewProjectionMatrix; 73 | uniform mat4 modelMatrix; 74 | uniform vec3 lightPosition; 75 | uniform vec3 viewPosition; 76 | 77 | mat3 transpose(mat3 m) { 78 | return mat3(m[0][0], m[1][0], m[2][0], 79 | m[0][1], m[1][1], m[2][1], 80 | m[0][2], m[1][2], m[2][2]); 81 | } 82 | 83 | 84 | void main() 85 | { 86 | vec4 pos = vec4(position, 1.0 ); 87 | vec3 posWorld = (modelMatrix * pos).xyz; 88 | 89 | // Tangent, Bitangent, Normal space matrix TBN 90 | // this is not entirely correct, it should use the normal matrix 91 | // In this special case it works out well, 92 | // since my model matrix does not contain any rotation or translation. 93 | // http://www.lighthouse3d.com/tutorials/glsl-12-tutorial/the-normal-matrix/ 94 | vec3 n = normalize((modelMatrix * vec4(normal, 0.0)).xyz); 95 | vec3 t = normalize((modelMatrix * vec4(tangent.xyz, 0.0)).xyz); 96 | vec3 b = normalize((modelMatrix * vec4((cross(normal, tangent.xyz) * tangent.w), 0.0)).xyz); 97 | mat3 tbn = transpose(mat3(t, b, n)); 98 | vLightDirection = tbn*(lightPosition - posWorld); 99 | vViewDirection = tbn*(viewPosition - posWorld); 100 | vTexCoord = texCoord; 101 | gl_Position = modelViewProjectionMatrix * pos; 102 | } 103 | |] 104 | 105 | 106 | normalFrag = 107 | [glsl| 108 | precision mediump float; 109 | 110 | uniform sampler2D textureDiff; 111 | uniform sampler2D textureNorm; 112 | 113 | varying vec2 vTexCoord; 114 | varying vec3 vLightDirection; 115 | varying vec3 vViewDirection; 116 | 117 | void main() { 118 | 119 | vec3 lightDir = normalize(vLightDirection); 120 | 121 | // Local normal, in tangent space 122 | vec3 pixelNormal = normalize(texture2D(textureNorm, vTexCoord).rgb*2.0 - 1.0); 123 | float lambert = max(dot(pixelNormal, lightDir), 0.0); 124 | 125 | 126 | // diffuse + lambert 127 | vec3 lightIntensities = vec3(1.5, 1.0, 1.0); 128 | vec3 diffuseColor = texture2D(textureDiff, vTexCoord).rgb; 129 | vec3 diffuse = lambert * diffuseColor * lightIntensities; 130 | 131 | // ambient 132 | vec3 ambient = 0.3 * diffuseColor; 133 | 134 | // specular 135 | float shininess = 32.0; 136 | vec3 viewDir = normalize(vViewDirection); 137 | vec3 reflectDir = reflect(-lightDir, pixelNormal); 138 | vec3 halfwayDir = normalize(lightDir + viewDir); 139 | float spec = pow(max(dot(pixelNormal, halfwayDir), 0.0), shininess); 140 | vec3 specular = vec3(0.2) * spec * lightIntensities; 141 | 142 | // attenuation 143 | float lightAttenuation = 0.3; 144 | float attenuation = 1.0 / (1.0 + lightAttenuation * pow(length(vLightDirection), 2.0)); 145 | 146 | vec3 final_color = ambient + (diffuse + specular) * attenuation; 147 | gl_FragColor = vec4(final_color, 1.0); 148 | } 149 | |] 150 | 151 | 152 | {-| same as the normal mapping shader, but without deforming normals. 153 | -} 154 | noNormalVert = 155 | [glsl| 156 | attribute vec3 position; 157 | attribute vec3 normal; 158 | attribute vec2 texCoord; 159 | 160 | varying vec2 vTexCoord; 161 | varying vec3 vLightDirection; 162 | varying vec3 vViewDirection; 163 | varying vec3 vNormal; 164 | 165 | uniform mat4 modelViewProjectionMatrix; 166 | uniform mat4 modelMatrix; 167 | uniform vec3 lightPosition; 168 | uniform vec3 viewPosition; 169 | 170 | void main() 171 | { 172 | vec4 pos = vec4(position, 1.0 ); 173 | vec3 posWorld = (modelMatrix * pos).xyz; 174 | 175 | vLightDirection = lightPosition - posWorld; 176 | vViewDirection = viewPosition - posWorld; 177 | vTexCoord = texCoord; 178 | // this is incorrect, it should use the normal matrix 179 | vNormal = mat3(modelMatrix) * normal; 180 | gl_Position = modelViewProjectionMatrix * pos; 181 | } 182 | |] 183 | 184 | 185 | noNormalFrag = 186 | [glsl| 187 | precision mediump float; 188 | 189 | uniform sampler2D textureDiff; 190 | 191 | varying vec2 vTexCoord; 192 | varying vec3 vLightDirection; 193 | varying vec3 vViewDirection; 194 | varying vec3 vNormal; 195 | 196 | void main() 197 | { 198 | vec3 lightDir = normalize(vLightDirection); 199 | 200 | // lambert 201 | vec3 pixelNormal = normalize(vNormal); 202 | float lambert = max(dot(pixelNormal, lightDir), 0.0); 203 | 204 | // diffuse + lambert 205 | vec3 lightIntensities = vec3(1.5, 1.0, 1.0); 206 | vec3 diffuseColor = texture2D(textureDiff, vTexCoord).rgb; 207 | vec3 diffuse = lambert * diffuseColor * lightIntensities; 208 | 209 | // ambient 210 | vec3 ambient = 0.3 * diffuseColor; 211 | 212 | // specular 213 | float shininess = 32.0; 214 | vec3 viewDir = normalize(vViewDirection); 215 | vec3 reflectDir = reflect(-lightDir, pixelNormal); 216 | vec3 halfwayDir = normalize(lightDir + viewDir); 217 | float spec = pow(max(dot(pixelNormal, halfwayDir), 0.0), shininess); 218 | vec3 specular = vec3(0.2) * spec * lightIntensities; 219 | 220 | // attenuation 221 | float lightAttenuation = 0.3; 222 | float attenuation = 1.0 / (1.0 + lightAttenuation * pow(length(vLightDirection), 2.0)); 223 | 224 | vec3 final_color = ambient + (diffuse + specular) * attenuation; 225 | gl_FragColor = vec4(final_color, 1.0); 226 | } 227 | |] 228 | 229 | 230 | {-| same as above, but without any textures. 231 | -} 232 | simpleVert = 233 | [glsl| 234 | attribute vec3 position; 235 | attribute vec3 normal; 236 | 237 | varying vec3 vLightDirection; 238 | varying vec3 vViewDirection; 239 | varying vec3 vNormal; 240 | 241 | uniform mat4 modelViewProjectionMatrix; 242 | uniform mat4 modelMatrix; 243 | uniform vec3 lightPosition; 244 | uniform vec3 viewPosition; 245 | 246 | void main() 247 | { 248 | vec4 pos = vec4(position, 1.0 ); 249 | vec3 posWorld = (modelMatrix * pos).xyz; 250 | 251 | vLightDirection = lightPosition - posWorld; 252 | vViewDirection = viewPosition - posWorld; 253 | // this is incorrect, it should use the normal matrix, like this: 254 | // vNormal = mat3(normalMatrix) * normal; 255 | // it works in this case, since the modelMatrix is the identity matrix 256 | vNormal = normal; 257 | gl_Position = modelViewProjectionMatrix * pos; 258 | } 259 | |] 260 | 261 | 262 | simpleFrag = 263 | [glsl| 264 | precision mediump float; 265 | 266 | varying vec3 vLightDirection; 267 | varying vec3 vViewDirection; 268 | varying vec3 vNormal; 269 | 270 | void main() 271 | { 272 | vec3 lightDir = normalize(vLightDirection); 273 | 274 | // lambert 275 | vec3 pixelNormal = normalize(vNormal); 276 | float lambert = max(dot(pixelNormal, lightDir), 0.0); 277 | 278 | // diffuse + lambert 279 | vec3 lightIntensities = vec3(1.5, 1.0, 1.0); 280 | vec3 diffuseColor = vec3(0.3, 0.2, 0.95); 281 | vec3 diffuse = lambert * diffuseColor * lightIntensities; 282 | 283 | // ambient 284 | vec3 ambient = 0.2 * diffuseColor; 285 | 286 | // specular 287 | float shininess = 32.0; 288 | vec3 viewDir = normalize(vViewDirection); 289 | vec3 reflectDir = reflect(-lightDir, pixelNormal); 290 | vec3 halfwayDir = normalize(lightDir + viewDir); 291 | float spec = pow(max(dot(pixelNormal, halfwayDir), 0.0), shininess); 292 | vec3 specular = vec3(0.2) * spec * lightIntensities; 293 | 294 | // attenuation 295 | float lightAttenuation = 0.3; 296 | float attenuation = 1.0 / (1.0 + lightAttenuation * pow(length(vLightDirection), 2.0)); 297 | 298 | vec3 final_color = ambient + (diffuse + specular) * attenuation; 299 | gl_FragColor = vec4(final_color, 1.0); 300 | } 301 | |] 302 | -------------------------------------------------------------------------------- /examples/Suzanne.elm: -------------------------------------------------------------------------------- 1 | module Suzanne exposing (Model, Msg(..), getCamera, initCmd, initModel, loadTexture, main, onZoom, renderModel, update, view) 2 | 3 | import Browser 4 | import Browser.Dom 5 | import Browser.Events exposing (onAnimationFrameDelta, onResize) 6 | import Html 7 | import Html.Attributes as Attr 8 | import Html.Events exposing (on) 9 | import Json.Decode as JD 10 | import Math.Matrix4 as M4 exposing (Mat4) 11 | import Math.Vector3 exposing (Vec3, vec3) 12 | import OBJ 13 | import OBJ.Types exposing (MeshWith, VertexWithTexture) 14 | import Shaders exposing (reflectionFrag, reflectionVert) 15 | import String exposing (fromInt) 16 | import Task 17 | import WebGL as GL 18 | import WebGL.Settings exposing (cullFace, front) 19 | import WebGL.Settings.DepthTest as DepthTest 20 | import WebGL.Texture exposing (Error(..), Texture) 21 | 22 | 23 | main : Program () Model Msg 24 | main = 25 | Browser.element 26 | { init = always ( initModel, initCmd ) 27 | , view = view 28 | , subscriptions = 29 | always <| 30 | Sub.batch 31 | [ onAnimationFrameDelta Tick 32 | , onResize ResizeWindow 33 | ] 34 | , update = update 35 | } 36 | 37 | 38 | 39 | -- MODEL 40 | 41 | 42 | type alias Model = 43 | { time : Float 44 | , mesh : Result String (MeshWith VertexWithTexture) 45 | , zoom : Float 46 | , width : Int 47 | , height : Int 48 | , reflectionTexture : Result String Texture 49 | } 50 | 51 | 52 | initModel : Model 53 | initModel = 54 | { mesh = Err "loading ...", time = 0, width = 640, height = 640, zoom = 1.5, reflectionTexture = Err "Loading texture..." } 55 | 56 | 57 | initCmd : Cmd Msg 58 | initCmd = 59 | Cmd.batch 60 | [ OBJ.loadMesh "meshes/suzanne.obj" LoadObj 61 | , loadTexture "textures/chavant.jpg" TextureLoaded 62 | , Task.perform 63 | (\{ viewport } -> 64 | ResizeWindow (round viewport.width) (round viewport.height) 65 | ) 66 | Browser.Dom.getViewport 67 | ] 68 | 69 | 70 | 71 | -- UPDATE 72 | 73 | 74 | type Msg 75 | = Tick Float 76 | | LoadObj (Result String (MeshWith VertexWithTexture)) 77 | | Zoom Float 78 | | ResizeWindow Int Int 79 | | TextureLoaded (Result String Texture) 80 | 81 | 82 | update : Msg -> Model -> ( Model, Cmd Msg ) 83 | update msg model = 84 | case msg of 85 | Tick dt -> 86 | ( { model | time = model.time + dt / 1000 }, Cmd.none ) 87 | 88 | Zoom dy -> 89 | ( { model | zoom = max 1 (model.zoom + dy / 15) }, Cmd.none ) 90 | 91 | LoadObj mesh -> 92 | ( { model | mesh = mesh }, Cmd.none ) 93 | 94 | TextureLoaded t -> 95 | ( { model | reflectionTexture = t }, Cmd.none ) 96 | 97 | ResizeWindow w h -> 98 | ( { model | width = w, height = h }, Cmd.none ) 99 | 100 | 101 | 102 | -- VIEW / RENDER 103 | 104 | 105 | renderModel : Model -> Texture -> MeshWith VertexWithTexture -> GL.Entity 106 | renderModel { zoom, time, width, height } texture { vertices, indices } = 107 | let 108 | aspect = 109 | toFloat width / toFloat height 110 | 111 | ( camera, view_ ) = 112 | getCamera aspect zoom time 113 | 114 | model = 115 | M4.makeRotate (0.6 * time) (vec3 0 1 0) 116 | 117 | modelView = 118 | M4.mul view_ model 119 | in 120 | GL.entityWith [ DepthTest.default, cullFace front ] 121 | reflectionVert 122 | reflectionFrag 123 | (GL.indexedTriangles vertices indices) 124 | { camera = camera, mvMat = modelView, texture = texture } 125 | 126 | 127 | getCamera : Float -> Float -> Float -> ( Mat4, Mat4 ) 128 | getCamera aspect zoom _ = 129 | let 130 | pos = 131 | 0.5 + zoom * zoom 132 | in 133 | ( M4.makePerspective 45 aspect 0.01 10000 134 | , M4.makeLookAt (vec3 pos (pos / 2) pos) (vec3 0 0 0) (vec3 0 1 0) 135 | ) 136 | 137 | 138 | view : Model -> Html.Html Msg 139 | view model = 140 | case ( model.mesh, model.reflectionTexture ) of 141 | ( Ok m, Ok t ) -> 142 | GL.toHtmlWith [ GL.antialias, GL.depth 1 ] 143 | [ onZoom, Attr.width model.width, Attr.height model.height ] 144 | [ renderModel model t m ] 145 | 146 | ( Err meshErr, Err reflectionErr ) -> 147 | Html.pre [] [ Html.text (meshErr ++ "\n\n\n" ++ reflectionErr) ] 148 | 149 | ( Err meshErr, Ok _ ) -> 150 | Html.pre [] [ Html.text <| "Mesh error: " ++ meshErr ] 151 | 152 | ( Ok _, Err reflectionErr ) -> 153 | Html.pre [] [ Html.text <| "Reflection error: " ++ reflectionErr ] 154 | 155 | 156 | 157 | -- HELPERS 158 | 159 | 160 | loadTexture : String -> (Result String Texture -> msg) -> Cmd msg 161 | loadTexture url msg = 162 | WebGL.Texture.load url 163 | |> Task.attempt 164 | (\r -> 165 | case r of 166 | Ok t -> 167 | msg (Ok t) 168 | 169 | Err LoadError -> 170 | msg (Err "Failed to load texture") 171 | 172 | Err (SizeError w h) -> 173 | msg (Err ("Invalid texture size: " ++ fromInt w ++ " x " ++ fromInt h)) 174 | ) 175 | 176 | 177 | onZoom : Html.Attribute Msg 178 | onZoom = 179 | on "wheel" (JD.map Zoom (JD.field "deltaY" JD.float)) 180 | -------------------------------------------------------------------------------- /examples/elm.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "application", 3 | "source-directories": [ 4 | ".", 5 | "../src" 6 | ], 7 | "elm-version": "0.19.1", 8 | "dependencies": { 9 | "direct": { 10 | "andre-dietrich/parser-combinators": "3.1.1", 11 | "elm/browser": "1.0.1", 12 | "elm/core": "1.0.2", 13 | "elm/html": "1.0.0", 14 | "elm/http": "1.0.0", 15 | "elm/json": "1.1.3", 16 | "elm/regex": "1.0.0", 17 | "elm/time": "1.0.0", 18 | "elm-explorations/linear-algebra": "1.0.3", 19 | "elm-explorations/webgl": "1.0.1" 20 | }, 21 | "indirect": { 22 | "elm/url": "1.0.0", 23 | "elm/virtual-dom": "1.0.2", 24 | "pilatch/flip": "1.0.0" 25 | } 26 | }, 27 | "test-dependencies": { 28 | "direct": {}, 29 | "indirect": {} 30 | } 31 | } -------------------------------------------------------------------------------- /examples/meshes/elmLogo.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.78 (sub 0) OBJ File: 'elmLogo.blend' 2 | # www.blender.org 3 | mtllib elmLogo.mtl 4 | o Cube.001 5 | v 1.471009 1.436646 0.059000 6 | v 1.500000 1.407655 0.100000 7 | v 1.528991 1.436646 0.059000 8 | v 1.478087 1.429568 0.089990 9 | v 1.500000 1.444863 0.085310 10 | v 1.521913 1.429568 0.089990 11 | v 1.500000 1.451482 0.059000 12 | v 1.063354 1.028991 0.059000 13 | v 1.063354 0.971009 0.059000 14 | v 1.092345 1.000000 0.100000 15 | v 1.048518 1.000000 0.059000 16 | v 1.055138 1.000000 0.085310 17 | v 1.070432 0.978087 0.089990 18 | v 1.070432 1.021914 0.089990 19 | v 1.471009 0.563354 0.059000 20 | v 1.528991 0.563354 0.059000 21 | v 1.500000 0.592345 0.100000 22 | v 1.500000 0.548518 0.059000 23 | v 1.500000 0.555137 0.085310 24 | v 1.521913 0.570432 0.089990 25 | v 1.478087 0.570432 0.089990 26 | v 1.936646 1.028991 0.059000 27 | v 1.907655 1.000000 0.100000 28 | v 1.936646 0.971009 0.059000 29 | v 1.929568 1.021913 0.089990 30 | v 1.944863 1.000000 0.085310 31 | v 1.929568 0.978087 0.089990 32 | v 1.951482 1.000000 0.059000 33 | v 1.099660 1.975702 0.059000 34 | v 1.087652 1.946711 0.059000 35 | v 1.157643 1.934702 0.100000 36 | v 1.075749 1.968624 0.059000 37 | v 1.090667 1.962444 0.086273 38 | v 1.115230 1.933289 0.089990 39 | v 1.128652 1.965692 0.089990 40 | v 1.546173 1.488190 0.059000 41 | v 1.546173 1.546173 0.100000 42 | v 1.488190 1.546173 0.059000 43 | v 1.538755 1.509764 0.089990 44 | v 1.521507 1.521507 0.085197 45 | v 1.509764 1.538755 0.089990 46 | v 1.517181 1.517181 0.059000 47 | v 1.975702 1.099660 0.059000 48 | v 1.934702 1.157643 0.100000 49 | v 1.946711 1.087652 0.059000 50 | v 1.965692 1.128652 0.089990 51 | v 1.962444 1.090667 0.086273 52 | v 1.933289 1.115230 0.089990 53 | v 1.968624 1.075749 0.059000 54 | v 1.934702 1.975702 0.059000 55 | v 1.934702 1.934702 0.100000 56 | v 1.975702 1.934702 0.059000 57 | v 1.934702 1.965692 0.089990 58 | v 1.961012 1.961012 0.085310 59 | v 1.965692 1.934702 0.089990 60 | v 1.965692 1.965692 0.059000 61 | v 1.912348 0.053289 0.059000 62 | v 1.842357 0.065298 0.100000 63 | v 1.900340 0.024298 0.059000 64 | v 1.884770 0.066711 0.089990 65 | v 1.909333 0.037556 0.086273 66 | v 1.871348 0.034308 0.089990 67 | v 1.924251 0.031377 0.059000 68 | v 1.511810 0.453827 0.059000 69 | v 1.453827 0.511810 0.059000 70 | v 1.453827 0.453827 0.100000 71 | v 1.482819 0.482819 0.059000 72 | v 1.478493 0.478493 0.085197 73 | v 1.461245 0.490236 0.089990 74 | v 1.490236 0.461245 0.089990 75 | v 0.971009 0.936646 0.059000 76 | v 1.000000 0.907655 0.100000 77 | v 1.028991 0.936646 0.059000 78 | v 0.978087 0.929568 0.089990 79 | v 1.000000 0.944863 0.085310 80 | v 1.021914 0.929568 0.089990 81 | v 1.000000 0.951482 0.059000 82 | v 0.087652 0.053289 0.059000 83 | v 0.099660 0.024298 0.059000 84 | v 0.157643 0.065298 0.100000 85 | v 0.075749 0.031376 0.059000 86 | v 0.090667 0.037556 0.086273 87 | v 0.128652 0.034308 0.089990 88 | v 0.115230 0.066711 0.089990 89 | v 1.946711 0.912348 0.059000 90 | v 1.934702 0.842357 0.100000 91 | v 1.975702 0.900340 0.059000 92 | v 1.933289 0.884770 0.089990 93 | v 1.962444 0.909333 0.086273 94 | v 1.965692 0.871348 0.089990 95 | v 1.968624 0.924251 0.059000 96 | v 1.563354 0.471009 0.059000 97 | v 1.592345 0.500000 0.100000 98 | v 1.563354 0.528991 0.059000 99 | v 1.570432 0.478087 0.089990 100 | v 1.555137 0.500000 0.085310 101 | v 1.570432 0.521913 0.089990 102 | v 1.548518 0.500000 0.059000 103 | v 1.975702 0.099660 0.059000 104 | v 1.934702 0.157643 0.100000 105 | v 1.946711 0.087652 0.059000 106 | v 1.965692 0.128652 0.089990 107 | v 1.962444 0.090667 0.086273 108 | v 1.933289 0.115230 0.089990 109 | v 1.968624 0.075749 0.059000 110 | v 0.024298 0.099660 0.059000 111 | v 0.053289 0.087652 0.059000 112 | v 0.065298 0.157643 0.100000 113 | v 0.031376 0.075749 0.059000 114 | v 0.037556 0.090667 0.086273 115 | v 0.066711 0.115230 0.089990 116 | v 0.034308 0.128652 0.089990 117 | v 0.936646 0.971009 0.059000 118 | v 0.936646 1.028991 0.059000 119 | v 0.907655 1.000000 0.100000 120 | v 0.951482 1.000000 0.059000 121 | v 0.944863 1.000000 0.085310 122 | v 0.929568 1.021914 0.089990 123 | v 0.929568 0.978087 0.089990 124 | v 0.453827 1.511810 0.059000 125 | v 0.453827 1.453827 0.100000 126 | v 0.511810 1.453827 0.059000 127 | v 0.461245 1.490236 0.089990 128 | v 0.478493 1.478493 0.085197 129 | v 0.490236 1.461245 0.089990 130 | v 0.482819 1.482819 0.059000 131 | v 0.053289 1.912348 0.059000 132 | v 0.024298 1.900340 0.059000 133 | v 0.065298 1.842357 0.100000 134 | v 0.031376 1.924251 0.059000 135 | v 0.037556 1.909333 0.086273 136 | v 0.034308 1.871348 0.089990 137 | v 0.066711 1.884770 0.089990 138 | v 1.400340 1.475702 0.059000 139 | v 1.342357 1.434702 0.100000 140 | v 1.412348 1.446711 0.059000 141 | v 1.371348 1.465692 0.089990 142 | v 1.409333 1.462444 0.086273 143 | v 1.384770 1.433289 0.089990 144 | v 1.424251 1.468624 0.059000 145 | v 0.599660 1.475702 0.059000 146 | v 0.587652 1.446711 0.059000 147 | v 0.657643 1.434702 0.100000 148 | v 0.575749 1.468624 0.059000 149 | v 0.590667 1.462444 0.086273 150 | v 0.615230 1.433289 0.089990 151 | v 0.628652 1.465692 0.089990 152 | v 0.971009 1.063354 0.059000 153 | v 1.028991 1.063354 0.059000 154 | v 1.000000 1.092345 0.100000 155 | v 1.000000 1.048518 0.059000 156 | v 1.000000 1.055138 0.085310 157 | v 1.021913 1.070432 0.089990 158 | v 0.978087 1.070432 0.089990 159 | v 0.099660 1.975702 0.059000 160 | v 0.087652 1.946711 0.059000 161 | v 0.157643 1.934702 0.100000 162 | v 0.075749 1.968624 0.059000 163 | v 0.090667 1.962444 0.086273 164 | v 0.115230 1.933289 0.089990 165 | v 0.128652 1.965692 0.089990 166 | v 0.551065 1.524298 0.059000 167 | v 0.527047 1.565298 0.100000 168 | v 0.481073 1.553289 0.059000 169 | v 0.539056 1.534308 0.089990 170 | v 0.514280 1.534474 0.086273 171 | v 0.496643 1.551876 0.089990 172 | v 0.512996 1.531376 0.059000 173 | v 1.412348 1.553289 0.059000 174 | v 1.342357 1.565298 0.100000 175 | v 1.400340 1.524298 0.059000 176 | v 1.384770 1.566711 0.089990 177 | v 1.409333 1.537556 0.086273 178 | v 1.371349 1.534308 0.089990 179 | v 1.424251 1.531376 0.059000 180 | v 0.948935 1.975702 0.059000 181 | v 0.972953 1.934702 0.100000 182 | v 1.018927 1.946711 0.059000 183 | v 0.960944 1.965692 0.089990 184 | v 0.985720 1.965526 0.086273 185 | v 1.003357 1.948124 0.089990 186 | v 0.987004 1.968624 0.059000 187 | v 0.948935 1.975702 -0.059000 188 | v 1.018927 1.946711 -0.059000 189 | v 0.972953 1.934702 -0.100000 190 | v 0.987004 1.968624 -0.059000 191 | v 0.985720 1.965526 -0.086273 192 | v 1.003357 1.948124 -0.089990 193 | v 0.960944 1.965692 -0.089990 194 | v 1.400340 1.524298 -0.059000 195 | v 1.342357 1.565298 -0.100000 196 | v 1.412348 1.553289 -0.059000 197 | v 1.371348 1.534308 -0.089990 198 | v 1.409333 1.537556 -0.086273 199 | v 1.384770 1.566711 -0.089990 200 | v 1.424251 1.531376 -0.059000 201 | v 0.481073 1.553289 -0.059000 202 | v 0.527047 1.565298 -0.100000 203 | v 0.551065 1.524298 -0.059000 204 | v 0.496643 1.551876 -0.089990 205 | v 0.514280 1.534474 -0.086273 206 | v 0.539056 1.534308 -0.089990 207 | v 0.512996 1.531376 -0.059000 208 | v 0.087652 1.946711 -0.059000 209 | v 0.099660 1.975702 -0.059000 210 | v 0.157643 1.934702 -0.100000 211 | v 0.075749 1.968624 -0.059000 212 | v 0.090667 1.962444 -0.086273 213 | v 0.128652 1.965692 -0.089990 214 | v 0.115230 1.933289 -0.089990 215 | v 0.971009 1.063354 -0.059000 216 | v 1.000000 1.092345 -0.100000 217 | v 1.028991 1.063354 -0.059000 218 | v 0.978087 1.070432 -0.089990 219 | v 1.000000 1.055137 -0.085310 220 | v 1.021914 1.070432 -0.089990 221 | v 1.000000 1.048518 -0.059000 222 | v 0.657643 1.434702 -0.100000 223 | v 0.587652 1.446711 -0.059000 224 | v 0.599660 1.475702 -0.059000 225 | v 0.615230 1.433289 -0.089990 226 | v 0.590667 1.462444 -0.086273 227 | v 0.575749 1.468624 -0.059000 228 | v 0.628652 1.465692 -0.089990 229 | v 1.342357 1.434702 -0.100000 230 | v 1.400340 1.475702 -0.059000 231 | v 1.412348 1.446711 -0.059000 232 | v 1.371348 1.465692 -0.089990 233 | v 1.409333 1.462444 -0.086273 234 | v 1.424251 1.468624 -0.059000 235 | v 1.384770 1.433289 -0.089990 236 | v 0.065298 1.842357 -0.100000 237 | v 0.024298 1.900340 -0.059000 238 | v 0.053289 1.912348 -0.059000 239 | v 0.034308 1.871348 -0.089990 240 | v 0.037556 1.909333 -0.086273 241 | v 0.031377 1.924251 -0.059000 242 | v 0.066711 1.884770 -0.089990 243 | v 0.453827 1.511810 -0.059000 244 | v 0.511810 1.453827 -0.059000 245 | v 0.453827 1.453827 -0.100000 246 | v 0.482819 1.482819 -0.059000 247 | v 0.478493 1.478493 -0.085197 248 | v 0.490236 1.461245 -0.089990 249 | v 0.461245 1.490236 -0.089990 250 | v 0.907655 1.000000 -0.100000 251 | v 0.936646 1.028991 -0.059000 252 | v 0.936646 0.971009 -0.059000 253 | v 0.929568 1.021913 -0.089990 254 | v 0.944863 1.000000 -0.085310 255 | v 0.951482 1.000000 -0.059000 256 | v 0.929568 0.978086 -0.089990 257 | v 0.053289 0.087652 -0.059000 258 | v 0.024298 0.099660 -0.059000 259 | v 0.065298 0.157643 -0.100000 260 | v 0.031376 0.075749 -0.059000 261 | v 0.037556 0.090667 -0.086273 262 | v 0.034308 0.128652 -0.089990 263 | v 0.066711 0.115230 -0.089990 264 | v 1.975702 0.099660 -0.059000 265 | v 1.946711 0.087652 -0.059000 266 | v 1.934702 0.157643 -0.100000 267 | v 1.968624 0.075749 -0.059000 268 | v 1.962444 0.090667 -0.086273 269 | v 1.933289 0.115230 -0.089990 270 | v 1.965692 0.128652 -0.089990 271 | v 1.563354 0.471009 -0.059000 272 | v 1.563354 0.528991 -0.059000 273 | v 1.592345 0.500000 -0.100000 274 | v 1.548518 0.500000 -0.059000 275 | v 1.555138 0.500000 -0.085310 276 | v 1.570432 0.521913 -0.089990 277 | v 1.570432 0.478087 -0.089990 278 | v 1.934702 0.842357 -0.100000 279 | v 1.946711 0.912348 -0.059000 280 | v 1.975702 0.900340 -0.059000 281 | v 1.933289 0.884770 -0.089990 282 | v 1.962444 0.909333 -0.086273 283 | v 1.968624 0.924251 -0.059000 284 | v 1.965692 0.871348 -0.089990 285 | v 0.157643 0.065298 -0.100000 286 | v 0.099660 0.024298 -0.059000 287 | v 0.087652 0.053289 -0.059000 288 | v 0.128652 0.034308 -0.089990 289 | v 0.090667 0.037556 -0.086273 290 | v 0.075749 0.031376 -0.059000 291 | v 0.115230 0.066711 -0.089990 292 | v 1.028991 0.936646 -0.059000 293 | v 1.000000 0.907655 -0.100000 294 | v 0.971009 0.936646 -0.059000 295 | v 1.021913 0.929568 -0.089990 296 | v 1.000000 0.944863 -0.085310 297 | v 0.978086 0.929568 -0.089990 298 | v 1.000000 0.951482 -0.059000 299 | v 1.511810 0.453827 -0.059000 300 | v 1.453827 0.453827 -0.100000 301 | v 1.453827 0.511810 -0.059000 302 | v 1.490236 0.461245 -0.089990 303 | v 1.478493 0.478493 -0.085197 304 | v 1.461245 0.490236 -0.089990 305 | v 1.482819 0.482819 -0.059000 306 | v 1.912348 0.053289 -0.059000 307 | v 1.900340 0.024298 -0.059000 308 | v 1.842357 0.065298 -0.100000 309 | v 1.924251 0.031376 -0.059000 310 | v 1.909333 0.037556 -0.086273 311 | v 1.871348 0.034308 -0.089990 312 | v 1.884770 0.066711 -0.089990 313 | v 1.934702 1.975702 -0.059000 314 | v 1.975702 1.934702 -0.059000 315 | v 1.934702 1.934702 -0.100000 316 | v 1.965692 1.965692 -0.059000 317 | v 1.961012 1.961012 -0.085310 318 | v 1.965692 1.934702 -0.089990 319 | v 1.934702 1.965692 -0.089990 320 | v 1.946711 1.087652 -0.059000 321 | v 1.934702 1.157643 -0.100000 322 | v 1.975702 1.099660 -0.059000 323 | v 1.933289 1.115230 -0.089990 324 | v 1.962444 1.090667 -0.086273 325 | v 1.965692 1.128652 -0.089990 326 | v 1.968624 1.075749 -0.059000 327 | v 1.546173 1.488190 -0.059000 328 | v 1.488190 1.546173 -0.059000 329 | v 1.546173 1.546173 -0.100000 330 | v 1.517181 1.517181 -0.059000 331 | v 1.521507 1.521507 -0.085197 332 | v 1.509764 1.538755 -0.089990 333 | v 1.538755 1.509764 -0.089990 334 | v 1.087652 1.946711 -0.059000 335 | v 1.099660 1.975702 -0.059000 336 | v 1.157643 1.934702 -0.100000 337 | v 1.075749 1.968624 -0.059000 338 | v 1.090667 1.962444 -0.086273 339 | v 1.128652 1.965692 -0.089990 340 | v 1.115230 1.933289 -0.089990 341 | v 1.936646 1.028991 -0.059000 342 | v 1.936646 0.971009 -0.059000 343 | v 1.907655 1.000000 -0.100000 344 | v 1.951482 1.000000 -0.059000 345 | v 1.944862 1.000000 -0.085310 346 | v 1.929568 0.978087 -0.089990 347 | v 1.929568 1.021914 -0.089990 348 | v 1.500000 0.592345 -0.100000 349 | v 1.528991 0.563354 -0.059000 350 | v 1.471009 0.563354 -0.059000 351 | v 1.521913 0.570432 -0.089990 352 | v 1.500000 0.555137 -0.085310 353 | v 1.500000 0.548518 -0.059000 354 | v 1.478087 0.570432 -0.089990 355 | v 1.063354 1.028991 -0.059000 356 | v 1.092345 1.000000 -0.100000 357 | v 1.063354 0.971009 -0.059000 358 | v 1.070432 1.021913 -0.089990 359 | v 1.055137 1.000000 -0.085310 360 | v 1.070432 0.978087 -0.089990 361 | v 1.048518 1.000000 -0.059000 362 | v 1.471009 1.436646 -0.059000 363 | v 1.528991 1.436646 -0.059000 364 | v 1.500000 1.407655 -0.100000 365 | v 1.500000 1.451482 -0.059000 366 | v 1.500000 1.444862 -0.085310 367 | v 1.521913 1.429568 -0.089990 368 | v 1.478087 1.429568 -0.089990 369 | vt 0.7148 0.7467 370 | vt 0.7417 0.7467 371 | vt 0.7417 0.8769 372 | vt 0.7148 0.8769 373 | vt 0.9182 0.5809 374 | vt 0.9451 0.5809 375 | vt 0.9451 0.7088 376 | vt 0.9182 0.7088 377 | vt 0.1594 0.7351 378 | vt 0.1862 0.7351 379 | vt 0.1862 0.8653 380 | vt 0.1594 0.8653 381 | vt 0.4604 0.7876 382 | vt 0.4872 0.7876 383 | vt 0.4872 0.9209 384 | vt 0.4604 0.9209 385 | vt 0.6104 0.7880 386 | vt 0.6373 0.7880 387 | vt 0.6373 0.9237 388 | vt 0.6104 0.9237 389 | vt 0.8177 0.6311 390 | vt 0.8446 0.6311 391 | vt 0.8446 0.9186 392 | vt 0.8177 0.9186 393 | vt 0.6527 0.0224 394 | vt 0.7369 0.1058 395 | vt 0.7369 0.2899 396 | vt 0.6527 0.2065 397 | vt 0.9638 0.7246 398 | vt 0.9907 0.7246 399 | vt 0.9907 0.8525 400 | vt 0.9638 0.8525 401 | vt 0.4196 0.4028 402 | vt 0.2277 0.2126 403 | vt 0.3311 0.1101 404 | vt 0.4196 0.0224 405 | vt 0.8727 0.4317 406 | vt 0.8995 0.4317 407 | vt 0.8995 0.7193 408 | vt 0.8727 0.7193 409 | vt 0.3126 0.8656 410 | vt 0.3395 0.8656 411 | vt 0.3395 0.9935 412 | vt 0.3126 0.9935 413 | vt 0.9638 0.5754 414 | vt 0.9907 0.5754 415 | vt 0.9907 0.6978 416 | vt 0.9638 0.6978 417 | vt 0.9638 0.4344 418 | vt 0.9907 0.4344 419 | vt 0.9907 0.5569 420 | vt 0.9638 0.5569 421 | vt 0.9741 0.1422 422 | vt 0.9472 0.1422 423 | vt 0.9472 0.0065 424 | vt 0.9741 0.0065 425 | vt 0.8830 0.2914 426 | vt 0.8561 0.2914 427 | vt 0.8561 0.0093 428 | vt 0.8830 0.0093 429 | vt 0.2051 0.4028 430 | vt 0.1166 0.3151 431 | vt 0.0132 0.2126 432 | vt 0.2051 0.0224 433 | vt 0.8727 0.7324 434 | vt 0.8995 0.7324 435 | vt 0.8995 0.8657 436 | vt 0.8727 0.8657 437 | vt 0.5059 0.7903 438 | vt 0.5328 0.7903 439 | vt 0.5328 0.9159 440 | vt 0.5059 0.9159 441 | vt 0.5515 0.7903 442 | vt 0.5784 0.7903 443 | vt 0.5784 0.9127 444 | vt 0.5515 0.9127 445 | vt 0.9182 0.7273 446 | vt 0.9451 0.7273 447 | vt 0.9451 0.8498 448 | vt 0.9182 0.8498 449 | vt 0.6104 0.6416 450 | vt 0.6373 0.6416 451 | vt 0.6373 0.7695 452 | vt 0.6104 0.7695 453 | vt 0.4736 0.6230 454 | vt 0.5621 0.5353 455 | vt 0.6506 0.4475 456 | vt 0.6506 0.6230 457 | vt 0.2049 0.7351 458 | vt 0.2318 0.7351 459 | vt 0.2318 0.8653 460 | vt 0.2049 0.8653 461 | vt 0.9016 0.0093 462 | vt 0.9285 0.0093 463 | vt 0.9285 0.1449 464 | vt 0.9016 0.1449 465 | vt 0.8540 0.6022 466 | vt 0.7760 0.5249 467 | vt 0.8540 0.4475 468 | vt 0.6693 0.7440 469 | vt 0.6962 0.7440 470 | vt 0.6962 0.8796 471 | vt 0.6693 0.8796 472 | vt 0.9182 0.4344 473 | vt 0.9451 0.4344 474 | vt 0.9451 0.5624 475 | vt 0.9182 0.5624 476 | vt 0.8374 0.0224 477 | vt 0.8374 0.1770 478 | vt 0.7594 0.0997 479 | vt 0.7534 0.4475 480 | vt 0.7534 0.6317 481 | vt 0.6693 0.7151 482 | vt 0.6693 0.5310 483 | vt 0.9016 0.1635 484 | vt 0.9285 0.1635 485 | vt 0.9285 0.2914 486 | vt 0.9016 0.2914 487 | vt 0.7721 0.6338 488 | vt 0.7990 0.6338 489 | vt 0.7990 0.9159 490 | vt 0.7721 0.9159 491 | vt 0.9741 0.2836 492 | vt 0.9472 0.2836 493 | vt 0.9472 0.1580 494 | vt 0.9741 0.1580 495 | vt 0.2505 0.7351 496 | vt 0.2774 0.7351 497 | vt 0.2774 0.8653 498 | vt 0.2505 0.8653 499 | vt 0.6340 0.0224 500 | vt 0.6340 0.4028 501 | vt 0.5455 0.3151 502 | vt 0.4421 0.2126 503 | vt 0.3258 0.7273 504 | vt 0.4361 0.7273 505 | vt 0.4361 0.8367 506 | vt 0.8374 0.2217 507 | vt 0.8374 0.3763 508 | vt 0.7594 0.2990 509 | vt 0.4417 0.6957 510 | vt 0.3165 0.5716 511 | vt 0.4417 0.4475 512 | vt 0.4417 0.5716 513 | vt 0.0225 0.7166 514 | vt 0.2939 0.4475 515 | vt 0.2939 0.7166 516 | vt 0.1477 0.7166 517 | vt 0.4604 0.6416 518 | vt 0.5917 0.6416 519 | vt 0.5917 0.7718 520 | vt 0.4604 0.7718 521 | vt 0.1956 0.7351 522 | vt 0.1956 0.7292 523 | vt 0.2049 0.7258 524 | vt 0.1407 0.8653 525 | vt 0.1500 0.8653 526 | vt 0.1500 0.8712 527 | vt 0.1407 0.8746 528 | vt 0.7148 0.8862 529 | vt 0.7088 0.8862 530 | vt 0.7055 0.8769 531 | vt 0.2049 0.8746 532 | vt 0.1989 0.8746 533 | vt 0.1956 0.8653 534 | vt 0.1500 0.7351 535 | vt 0.1500 0.7292 536 | vt 0.1594 0.7258 537 | vt 0.0093 0.8653 538 | vt 0.0093 0.8746 539 | vt 0.0033 0.8746 540 | vt 0.0000 0.8653 541 | vt 0.1594 0.8746 542 | vt 0.1534 0.8746 543 | vt 0.1500 0.8653 544 | vt 0.2411 0.7351 545 | vt 0.2411 0.7292 546 | vt 0.2505 0.7258 547 | vt 0.0093 0.7351 548 | vt 0.0000 0.7351 549 | vt 0.0000 0.7292 550 | vt 0.0093 0.7258 551 | vt 0.7055 0.7467 552 | vt 0.7055 0.7408 553 | vt 0.7148 0.7375 554 | vt 0.1407 0.7351 555 | vt 0.1407 0.7258 556 | vt 0.1467 0.7258 557 | vt 0.1500 0.7351 558 | vt 0.2505 0.8746 559 | vt 0.2445 0.8746 560 | vt 0.2411 0.8653 561 | vt 0.4604 0.9275 562 | vt 0.4541 0.9275 563 | vt 0.4510 0.9163 564 | vt 0.9089 0.4410 565 | vt 0.9089 0.4324 566 | vt 0.9182 0.4252 567 | vt 0.4670 0.6323 568 | vt 0.4583 0.6323 569 | vt 0.4623 0.6211 570 | vt 0.9089 0.5763 571 | vt 0.9089 0.5716 572 | vt 0.9182 0.5716 573 | vt 0.5522 0.5320 574 | vt 0.5555 0.5287 575 | vt 0.5588 0.5255 576 | vt 0.9122 0.5716 577 | vt 0.9089 0.5670 578 | vt 0.8633 0.7370 579 | vt 0.8633 0.7310 580 | vt 0.8727 0.7258 581 | vt 0.6487 0.4364 582 | vt 0.6548 0.4303 583 | vt 0.6599 0.4410 584 | vt 0.9182 0.7181 585 | vt 0.9120 0.7181 586 | vt 0.9089 0.7023 587 | vt 0.4510 0.7876 588 | vt 0.4510 0.7834 589 | vt 0.4604 0.7810 590 | vt 0.6599 0.6230 591 | vt 0.6599 0.6290 592 | vt 0.6506 0.6323 593 | vt 0.8727 0.8723 594 | vt 0.8667 0.8723 595 | vt 0.8633 0.8657 596 | vt 0.6010 0.6481 597 | vt 0.6010 0.6395 598 | vt 0.6104 0.6323 599 | vt 0.2145 0.4094 600 | vt 0.2145 0.4180 601 | vt 0.2032 0.4140 602 | vt 0.8177 0.9252 603 | vt 0.8115 0.9252 604 | vt 0.8083 0.9140 605 | vt 0.6104 0.7787 606 | vt 0.6044 0.7787 607 | vt 0.6010 0.7741 608 | vt 0.6010 0.7834 609 | vt 0.6010 0.7787 610 | vt 0.1133 0.3249 611 | vt 0.1100 0.3216 612 | vt 0.1067 0.3184 613 | vt 0.7628 0.6338 614 | vt 0.7628 0.6279 615 | vt 0.7721 0.6245 616 | vt 0.0066 0.2191 617 | vt 0.0024 0.2149 618 | vt 0.0066 0.2060 619 | vt 0.6104 0.9329 620 | vt 0.6044 0.9329 621 | vt 0.6010 0.9237 622 | vt 0.7721 0.9252 623 | vt 0.7659 0.9252 624 | vt 0.7628 0.9094 625 | vt 0.8083 0.6357 626 | vt 0.8083 0.6296 627 | vt 0.8177 0.6245 628 | vt 0.2032 0.0112 629 | vt 0.2093 0.0051 630 | vt 0.2145 0.0158 631 | vt 0.9544 0.4410 632 | vt 0.9544 0.4324 633 | vt 0.9638 0.4252 634 | vt 0.8633 0.6087 635 | vt 0.8633 0.6173 636 | vt 0.8520 0.6134 637 | vt 0.9638 0.8590 638 | vt 0.9576 0.8590 639 | vt 0.9544 0.8479 640 | vt 0.9089 0.7273 641 | vt 0.9089 0.7214 642 | vt 0.9182 0.7181 643 | vt 0.7694 0.5314 644 | vt 0.7651 0.5272 645 | vt 0.7694 0.5183 646 | vt 0.9638 0.5661 647 | vt 0.9578 0.5661 648 | vt 0.9544 0.5569 649 | vt 0.9544 0.7293 650 | vt 0.9544 0.7232 651 | vt 0.9638 0.7181 652 | vt 0.8520 0.4364 653 | vt 0.8582 0.4303 654 | vt 0.8633 0.4410 655 | vt 0.9182 0.8590 656 | vt 0.9120 0.8590 657 | vt 0.9089 0.8432 658 | vt 0.8727 0.7258 659 | vt 0.8664 0.7258 660 | vt 0.8633 0.7147 661 | vt 0.8923 0.2848 662 | vt 0.8923 0.2934 663 | vt 0.8830 0.3007 664 | vt 0.4289 0.4094 665 | vt 0.4289 0.4180 666 | vt 0.4176 0.4140 667 | vt 0.8830 0.0000 668 | vt 0.8890 0.0000 669 | vt 0.8923 0.0093 670 | vt 0.8923 0.0093 671 | vt 0.8923 0.0033 672 | vt 0.9016 0.0000 673 | vt 0.2211 0.2191 674 | vt 0.2168 0.2149 675 | vt 0.2211 0.2060 676 | vt 0.8923 0.1588 677 | vt 0.8923 0.1542 678 | vt 0.9016 0.1542 679 | vt 0.3211 0.1068 680 | vt 0.3244 0.1036 681 | vt 0.3277 0.1003 682 | vt 0.8957 0.1542 683 | vt 0.8923 0.1496 684 | vt 0.9016 0.3007 685 | vt 0.8954 0.3007 686 | vt 0.8923 0.2848 687 | vt 0.8633 0.4364 688 | vt 0.8633 0.4303 689 | vt 0.8727 0.4252 690 | vt 0.4176 0.0112 691 | vt 0.4238 0.0051 692 | vt 0.4289 0.0158 693 | vt 0.3033 0.8702 694 | vt 0.3033 0.8642 695 | vt 0.3126 0.8590 696 | vt 0.8355 0.0112 697 | vt 0.8416 0.0051 698 | vt 0.8467 0.0158 699 | vt 0.9638 0.7071 700 | vt 0.9576 0.7071 701 | vt 0.9544 0.6913 702 | vt 0.3126 1.0000 703 | vt 0.3064 1.0000 704 | vt 0.3033 0.9888 705 | vt 0.5421 0.7968 706 | vt 0.5421 0.7882 707 | vt 0.5515 0.7810 708 | vt 0.8467 0.1835 709 | vt 0.8467 0.1921 710 | vt 0.8355 0.1882 711 | vt 0.5515 0.9220 712 | vt 0.5455 0.9220 713 | vt 0.5421 0.9127 714 | vt 0.9544 0.5754 715 | vt 0.9544 0.5695 716 | vt 0.9638 0.5661 717 | vt 0.7528 0.1062 718 | vt 0.7486 0.1020 719 | vt 0.7528 0.0931 720 | vt 0.9741 0.0000 721 | vt 0.9803 0.0000 722 | vt 0.9834 0.0112 723 | vt 0.4966 0.7968 724 | vt 0.4966 0.7882 725 | vt 0.5059 0.7810 726 | vt 0.6434 0.0158 727 | vt 0.6434 0.0072 728 | vt 0.6546 0.0112 729 | vt 0.6599 0.7421 730 | vt 0.6599 0.7381 731 | vt 0.6693 0.7375 732 | vt 0.7415 0.0973 733 | vt 0.7455 0.1013 734 | vt 0.7462 0.1085 735 | vt 0.5059 0.9252 736 | vt 0.4997 0.9252 737 | vt 0.4966 0.9186 738 | vt 0.9834 0.2771 739 | vt 0.9834 0.2857 740 | vt 0.9741 0.2929 741 | vt 0.7462 0.2965 742 | vt 0.7462 0.3050 743 | vt 0.7349 0.3011 744 | vt 0.6693 0.8862 745 | vt 0.6631 0.8862 746 | vt 0.6599 0.8750 747 | vt 0.9834 0.1441 748 | vt 0.9834 0.1480 749 | vt 0.9741 0.1487 750 | vt 0.6480 0.2150 751 | vt 0.6440 0.2110 752 | vt 0.6434 0.2038 753 | vt 0.9803 0.1487 754 | vt 0.9834 0.1553 755 | vt 0.9472 0.1487 756 | vt 0.9410 0.1487 757 | vt 0.9379 0.1441 758 | vt 0.9379 0.1553 759 | vt 0.9379 0.1497 760 | vt 0.7628 0.6290 761 | vt 0.7628 0.6346 762 | vt 0.7581 0.6401 763 | vt 0.7055 0.8750 764 | vt 0.7055 0.8811 765 | vt 0.6962 0.8862 766 | vt 0.6712 0.7263 767 | vt 0.6651 0.7323 768 | vt 0.6599 0.7216 769 | vt 0.9472 0.2929 770 | vt 0.9410 0.2929 771 | vt 0.9379 0.2771 772 | vt 0.5421 0.9186 773 | vt 0.5421 0.9242 774 | vt 0.5328 0.9252 775 | vt 0.6599 0.5337 776 | vt 0.6599 0.5281 777 | vt 0.6646 0.5225 778 | vt 0.6962 0.7375 779 | vt 0.7024 0.7375 780 | vt 0.7055 0.7421 781 | vt 0.5328 0.7810 782 | vt 0.5390 0.7810 783 | vt 0.5421 0.7968 784 | vt 0.9379 0.0112 785 | vt 0.9379 0.0051 786 | vt 0.9472 0.0000 787 | vt 0.7515 0.4364 788 | vt 0.7576 0.4303 789 | vt 0.7628 0.4410 790 | vt 0.5877 0.9127 791 | vt 0.5877 0.9187 792 | vt 0.5784 0.9220 793 | vt 0.4361 0.7181 794 | vt 0.4421 0.7181 795 | vt 0.4455 0.7273 796 | vt 0.9907 0.5661 797 | vt 0.9967 0.5661 798 | vt 1.0000 0.5754 799 | vt 0.4455 0.8432 800 | vt 0.4455 0.8518 801 | vt 0.4342 0.8479 802 | vt 0.5784 0.7810 803 | vt 0.5846 0.7810 804 | vt 0.5877 0.7968 805 | vt 0.3488 0.9888 806 | vt 0.3488 0.9949 807 | vt 0.3395 1.0000 808 | vt 0.3146 0.7293 809 | vt 0.3084 0.7232 810 | vt 0.3192 0.7181 811 | vt 0.3395 0.8590 812 | vt 0.3457 0.8590 813 | vt 0.3488 0.8702 814 | vt 1.0000 0.6913 815 | vt 1.0000 0.6999 816 | vt 0.9907 0.7071 817 | vt 0.6434 0.4094 818 | vt 0.6434 0.4180 819 | vt 0.6321 0.4140 820 | vt 0.8995 0.4252 821 | vt 0.9057 0.4252 822 | vt 0.9089 0.4364 823 | vt 0.9379 0.2848 824 | vt 0.9379 0.2934 825 | vt 0.9285 0.3007 826 | vt 0.9285 0.1542 827 | vt 0.9345 0.1542 828 | vt 0.9379 0.1588 829 | vt 0.9379 0.1496 830 | vt 0.9379 0.1542 831 | vt 0.5422 0.3249 832 | vt 0.5389 0.3216 833 | vt 0.5356 0.3184 834 | vt 0.4355 0.2191 835 | vt 0.4313 0.2149 836 | vt 0.4355 0.2060 837 | vt 0.9285 0.0000 838 | vt 0.9345 0.0000 839 | vt 0.9379 0.0093 840 | vt 0.8467 0.0093 841 | vt 0.8467 0.0033 842 | vt 0.8561 0.0000 843 | vt 0.8561 0.3007 844 | vt 0.8499 0.3007 845 | vt 0.8467 0.2848 846 | vt 0.9089 0.7147 847 | vt 0.9089 0.7207 848 | vt 0.8995 0.7258 849 | vt 0.6321 0.0112 850 | vt 0.6382 0.0051 851 | vt 0.6434 0.0158 852 | vt 0.9907 0.7181 853 | vt 0.9969 0.7181 854 | vt 1.0000 0.7293 855 | vt 0.9544 0.8432 856 | vt 0.9544 0.8518 857 | vt 0.9451 0.8590 858 | vt 0.8467 0.3829 859 | vt 0.8467 0.3915 860 | vt 0.8355 0.3875 861 | vt 0.9451 0.7181 862 | vt 0.9511 0.7181 863 | vt 0.9544 0.7273 864 | vt 1.0000 0.5569 865 | vt 1.0000 0.5628 866 | vt 0.9907 0.5661 867 | vt 0.7528 0.3056 868 | vt 0.7486 0.3014 869 | vt 0.7528 0.2925 870 | vt 0.8355 0.2105 871 | vt 0.8416 0.2045 872 | vt 0.8467 0.2152 873 | vt 0.9907 0.4252 874 | vt 0.9969 0.4252 875 | vt 1.0000 0.4410 876 | vt 1.0000 0.8479 877 | vt 1.0000 0.8539 878 | vt 0.9907 0.8590 879 | vt 0.2920 0.4364 880 | vt 0.2981 0.4303 881 | vt 0.3033 0.4410 882 | vt 0.8446 0.6245 883 | vt 0.8508 0.6245 884 | vt 0.8539 0.6357 885 | vt 0.8083 0.9094 886 | vt 0.8083 0.9180 887 | vt 0.7990 0.9252 888 | vt 0.6466 0.9237 889 | vt 0.6466 0.9296 890 | vt 0.6373 0.9329 891 | vt 0.3033 0.7166 892 | vt 0.3033 0.7225 893 | vt 0.2939 0.7258 894 | vt 0.7990 0.6245 895 | vt 0.8050 0.6245 896 | vt 0.8083 0.6338 897 | vt 0.6466 0.7741 898 | vt 0.6466 0.7787 899 | vt 0.6373 0.7787 900 | vt 0.1524 0.7258 901 | vt 0.1477 0.7258 902 | vt 0.1431 0.7258 903 | vt 0.6432 0.7787 904 | vt 0.6466 0.7834 905 | vt 0.6373 0.6323 906 | vt 0.6435 0.6323 907 | vt 0.6466 0.6481 908 | vt 0.8539 0.9140 909 | vt 0.8539 0.9201 910 | vt 0.8446 0.9252 911 | vt 0.0159 0.7258 912 | vt 0.0073 0.7258 913 | vt 0.0113 0.7147 914 | vt 0.4872 0.7810 915 | vt 0.4932 0.7810 916 | vt 0.4966 0.7876 917 | vt 0.9089 0.8657 918 | vt 0.9089 0.8699 919 | vt 0.8995 0.8723 920 | vt 0.3099 0.5782 921 | vt 0.3056 0.5740 922 | vt 0.3099 0.5651 923 | vt 0.9544 0.7023 924 | vt 0.9544 0.7109 925 | vt 0.9451 0.7181 926 | vt 0.4397 0.4364 927 | vt 0.4459 0.4303 928 | vt 0.4510 0.4410 929 | vt 0.8995 0.7258 930 | vt 0.9057 0.7258 931 | vt 0.9089 0.7370 932 | vt 0.9451 0.5716 933 | vt 0.9511 0.5716 934 | vt 0.9544 0.5763 935 | vt 0.9544 0.5670 936 | vt 0.9544 0.5716 937 | vt 0.4510 0.5670 938 | vt 0.4510 0.5716 939 | vt 0.4510 0.5763 940 | vt 0.9451 0.4252 941 | vt 0.9513 0.4252 942 | vt 0.9544 0.4410 943 | vt 0.4966 0.9163 944 | vt 0.4966 0.9224 945 | vt 0.4872 0.9275 946 | vt 0.4510 0.7023 947 | vt 0.4510 0.7109 948 | vt 0.4397 0.7069 949 | vt 0.7417 0.7375 950 | vt 0.7477 0.7375 951 | vt 0.7511 0.7467 952 | vt 0.2867 0.8653 953 | vt 0.2867 0.8712 954 | vt 0.2774 0.8746 955 | vt 0.5917 0.6323 956 | vt 0.5977 0.6323 957 | vt 0.6010 0.6416 958 | vt 0.6010 0.7718 959 | vt 0.6010 0.7777 960 | vt 0.5917 0.7810 961 | vt 0.2774 0.7258 962 | vt 0.2834 0.7258 963 | vt 0.2867 0.7351 964 | vt 0.1956 0.8653 965 | vt 0.1956 0.8712 966 | vt 0.1862 0.8746 967 | vt 0.2411 0.8653 968 | vt 0.2411 0.8712 969 | vt 0.2318 0.8746 970 | vt 0.4604 0.7810 971 | vt 0.4544 0.7810 972 | vt 0.4510 0.7718 973 | vt 0.1862 0.7258 974 | vt 0.1922 0.7258 975 | vt 0.1956 0.7351 976 | vt 0.2318 0.7258 977 | vt 0.2378 0.7258 978 | vt 0.2411 0.7351 979 | vt 0.7511 0.8769 980 | vt 0.7511 0.8829 981 | vt 0.7417 0.8862 982 | vt 0.4510 0.6416 983 | vt 0.4510 0.6356 984 | vt 0.4604 0.6323 985 | vn 0.7936 0.5914 0.1429 986 | vn 0.7936 0.5914 -0.1429 987 | vn 0.5914 0.7936 -0.1429 988 | vn 0.5914 0.7936 0.1429 989 | vn -0.6945 -0.7033 0.1517 990 | vn -0.6945 -0.7033 -0.1517 991 | vn -0.5914 -0.7855 -0.1820 992 | vn -0.5914 -0.7855 0.1820 993 | vn -0.7936 -0.5914 0.1429 994 | vn -0.7936 -0.5914 -0.1429 995 | vn -0.5914 -0.7936 -0.1429 996 | vn -0.5914 -0.7936 0.1429 997 | vn 0.1429 0.9793 0.1429 998 | vn 0.1429 0.9793 -0.1429 999 | vn -0.1373 0.9736 -0.1820 1000 | vn -0.1373 0.9736 0.1820 1001 | vn 0.6945 0.7033 0.1517 1002 | vn 0.6945 0.7033 -0.1517 1003 | vn -0.1373 -0.9736 0.1820 1004 | vn -0.1373 -0.9736 -0.1820 1005 | vn 0.1373 -0.9736 -0.1820 1006 | vn 0.1373 -0.9736 0.1820 1007 | vn -0.1067 0.0442 0.9933 1008 | vn -0.0774 -0.1869 0.9793 1009 | vn 0.1067 -0.0442 0.9933 1010 | vn 0.0774 0.1869 0.9793 1011 | vn 0.9736 -0.1373 0.1820 1012 | vn 0.9736 -0.1373 -0.1820 1013 | vn 0.9736 0.1373 -0.1820 1014 | vn 0.9736 0.1373 0.1820 1015 | vn -0.0442 -0.1067 0.9933 1016 | vn 0.2022 0.0000 0.9793 1017 | vn 0.1210 0.1210 0.9852 1018 | vn -0.0442 0.1067 0.9933 1019 | vn -0.9736 0.1373 0.1820 1020 | vn -0.9736 0.1373 -0.1820 1021 | vn -0.9736 -0.1373 -0.1820 1022 | vn -0.9736 -0.1373 0.1820 1023 | vn 0.1373 0.9736 0.1820 1024 | vn 0.1373 0.9736 -0.1820 1025 | vn 0.5914 -0.7936 0.1429 1026 | vn 0.5914 -0.7936 -0.1429 1027 | vn 0.7855 -0.5914 -0.1820 1028 | vn 0.7855 -0.5914 0.1820 1029 | vn -0.5914 0.7855 0.1820 1030 | vn -0.5914 0.7855 -0.1820 1031 | vn -0.7936 0.5914 -0.1429 1032 | vn -0.7936 0.5914 0.1429 1033 | vn 0.0701 0.9886 0.1333 1034 | vn 0.0701 0.9886 -0.1333 1035 | vn 0.5914 -0.7855 0.1820 1036 | vn 0.5914 -0.7855 -0.1820 1037 | vn 0.7936 -0.5914 -0.1429 1038 | vn 0.7936 -0.5914 0.1429 1039 | vn 0.0000 0.2022 0.9793 1040 | vn -0.1067 -0.0442 0.9933 1041 | vn 0.9793 0.1429 -0.1429 1042 | vn 0.9793 0.1429 0.1429 1043 | vn -0.7855 -0.5914 0.1820 1044 | vn -0.7855 -0.5914 -0.1820 1045 | vn -0.6494 -0.7486 -0.1333 1046 | vn -0.6494 -0.7486 0.1333 1047 | vn 0.7855 0.5914 0.1820 1048 | vn 0.7855 0.5914 -0.1820 1049 | vn 0.7033 0.6945 -0.1517 1050 | vn 0.7033 0.6945 0.1517 1051 | vn -0.1210 -0.1210 0.9852 1052 | vn 0.0442 -0.1067 0.9933 1053 | vn 0.1429 0.1429 0.9793 1054 | vn -0.5914 0.7936 0.1429 1055 | vn -0.5914 0.7936 -0.1429 1056 | vn 0.0442 0.1067 0.9933 1057 | vn -0.2022 0.0000 0.9793 1058 | vn -0.0701 -0.9886 0.1333 1059 | vn -0.0701 -0.9886 -0.1333 1060 | vn -0.7033 -0.6945 -0.1517 1061 | vn -0.7033 -0.6945 0.1517 1062 | vn 0.1067 0.0442 0.9933 1063 | vn 0.0000 -0.2022 0.9793 1064 | vn -0.1067 0.0442 -0.9933 1065 | vn 0.0774 0.1869 -0.9793 1066 | vn 0.1067 -0.0442 -0.9933 1067 | vn -0.0774 -0.1869 -0.9793 1068 | vn 0.5914 0.7855 -0.1820 1069 | vn 0.5914 0.7855 0.1820 1070 | vn -0.7855 0.5914 -0.1820 1071 | vn -0.7855 0.5914 0.1820 1072 | vn 0.6494 0.7486 -0.1333 1073 | vn 0.6494 0.7486 0.1333 1074 | vn -0.0442 -0.1067 -0.9933 1075 | vn -0.0442 0.1067 -0.9933 1076 | vn 0.1210 0.1210 -0.9852 1077 | vn 0.2022 0.0000 -0.9793 1078 | vn 0.1067 0.0442 -0.9933 1079 | vn 0.0000 -0.2022 -0.9793 1080 | vn 0.0442 0.1067 -0.9933 1081 | vn 0.0442 -0.1067 -0.9933 1082 | vn -0.2022 0.0000 -0.9793 1083 | vn 0.1429 0.1429 -0.9793 1084 | vn -0.1210 -0.1210 -0.9852 1085 | vn -0.1067 -0.0442 -0.9933 1086 | vn 0.0000 0.2022 -0.9793 1087 | vn -0.3939 0.5958 0.6999 1088 | vn 0.0000 0.8165 0.5773 1089 | vn 0.0000 0.9897 0.1428 1090 | vn 0.3939 0.5958 0.6999 1091 | vn -0.9897 0.0000 0.1428 1092 | vn -0.8165 0.0000 0.5773 1093 | vn -0.5958 0.3939 0.6999 1094 | vn -0.5958 -0.3939 0.6999 1095 | vn 0.0000 -0.9897 0.1428 1096 | vn 0.0000 -0.8165 0.5773 1097 | vn -0.3939 -0.5958 0.6999 1098 | vn 0.3939 -0.5958 0.6999 1099 | vn 0.5958 0.3939 0.6999 1100 | vn 0.8165 0.0000 0.5773 1101 | vn 0.9897 0.0000 0.1428 1102 | vn 0.5958 -0.3939 0.6999 1103 | vn -0.8891 0.3683 0.2718 1104 | vn -0.6227 0.2579 0.7387 1105 | vn -0.0997 0.6339 0.7669 1106 | vn -0.5188 -0.3777 0.7669 1107 | vn -0.4820 -0.5001 0.7194 1108 | vn -0.5650 -0.5650 0.6012 1109 | vn -0.6998 -0.6998 0.1435 1110 | vn -0.5001 -0.4820 0.7194 1111 | vn 0.6339 -0.0997 0.7669 1112 | vn 0.2579 -0.6227 0.7387 1113 | vn 0.3683 -0.8891 0.2718 1114 | vn -0.3777 -0.5188 0.7669 1115 | vn 0.1428 0.6999 0.6999 1116 | vn 0.5773 0.5773 0.5773 1117 | vn 0.6999 0.6999 0.1428 1118 | vn 0.6999 0.1428 0.6999 1119 | vn 0.5188 0.3777 0.7669 1120 | vn 0.6227 -0.2579 0.7387 1121 | vn 0.8891 -0.3683 0.2718 1122 | vn 0.0997 -0.6339 0.7669 1123 | vn 0.6998 0.6998 0.1435 1124 | vn 0.5650 0.5650 0.6012 1125 | vn 0.5001 0.4820 0.7194 1126 | vn 0.4820 0.5001 0.7194 1127 | vn -0.8891 -0.3683 0.2718 1128 | vn -0.6227 -0.2579 0.7387 1129 | vn -0.5188 0.3777 0.7669 1130 | vn -0.0997 -0.6339 0.7669 1131 | vn -0.3777 0.5188 0.7669 1132 | vn 0.2579 0.6227 0.7387 1133 | vn 0.3683 0.8891 0.2718 1134 | vn 0.6339 0.0997 0.7669 1135 | vn -0.3683 -0.8891 0.2718 1136 | vn -0.2579 -0.6227 0.7387 1137 | vn -0.6339 -0.0997 0.7669 1138 | vn 0.3777 -0.5188 0.7669 1139 | vn -0.3683 0.8891 0.2718 1140 | vn -0.2579 0.6227 0.7387 1141 | vn 0.3777 0.5188 0.7669 1142 | vn -0.6339 0.0997 0.7669 1143 | vn 0.0997 0.6339 0.7669 1144 | vn 0.6227 0.2579 0.7387 1145 | vn 0.8891 0.3683 0.2718 1146 | vn 0.5188 -0.3777 0.7669 1147 | vn -0.0745 -0.7240 0.6857 1148 | vn -0.3177 -0.7669 0.5575 1149 | vn -0.3807 -0.9192 0.1005 1150 | vn -0.4593 -0.5646 0.6857 1151 | vn 0.0745 0.7240 0.6857 1152 | vn 0.3177 0.7669 0.5575 1153 | vn 0.3807 0.9192 0.1005 1154 | vn 0.4593 0.5646 0.6857 1155 | vn 0.3807 0.9192 -0.1005 1156 | vn 0.3177 0.7669 -0.5575 1157 | vn 0.0745 0.7240 -0.6857 1158 | vn 0.4593 0.5646 -0.6857 1159 | vn 0.0997 -0.6339 -0.7669 1160 | vn 0.6227 -0.2579 -0.7387 1161 | vn 0.8891 -0.3683 -0.2718 1162 | vn 0.5188 0.3777 -0.7669 1163 | vn -0.4593 -0.5646 -0.6857 1164 | vn -0.3177 -0.7669 -0.5575 1165 | vn -0.3807 -0.9192 -0.1005 1166 | vn -0.0745 -0.7240 -0.6857 1167 | vn -0.8891 0.3683 -0.2718 1168 | vn -0.6227 0.2579 -0.7387 1169 | vn -0.5188 -0.3777 -0.7669 1170 | vn -0.0997 0.6339 -0.7669 1171 | vn -0.3939 -0.5958 -0.6999 1172 | vn 0.0000 -0.8165 -0.5773 1173 | vn 0.0000 -0.9897 -0.1428 1174 | vn 0.3939 -0.5958 -0.6999 1175 | vn 0.0997 0.6339 -0.7669 1176 | vn 0.6227 0.2579 -0.7387 1177 | vn 0.5188 -0.3777 -0.7669 1178 | vn 0.8891 0.3683 -0.2718 1179 | vn -0.6339 0.0997 -0.7669 1180 | vn -0.2579 0.6227 -0.7387 1181 | vn 0.3777 0.5188 -0.7669 1182 | vn -0.3683 0.8891 -0.2718 1183 | vn 0.6998 0.6998 -0.1435 1184 | vn 0.5650 0.5650 -0.6012 1185 | vn 0.4820 0.5001 -0.7194 1186 | vn 0.5001 0.4820 -0.7194 1187 | vn 0.5958 0.3939 -0.6999 1188 | vn 0.8165 0.0000 -0.5773 1189 | vn 0.5958 -0.3939 -0.6999 1190 | vn 0.9897 0.0000 -0.1428 1191 | vn -0.3683 -0.8891 -0.2718 1192 | vn -0.2579 -0.6227 -0.7387 1193 | vn 0.3777 -0.5188 -0.7669 1194 | vn -0.6339 -0.0997 -0.7669 1195 | vn 0.3683 -0.8891 -0.2718 1196 | vn 0.2579 -0.6227 -0.7387 1197 | vn 0.6339 -0.0997 -0.7669 1198 | vn -0.3777 -0.5188 -0.7669 1199 | vn -0.9897 0.0000 -0.1428 1200 | vn -0.8165 0.0000 -0.5773 1201 | vn -0.5958 -0.3939 -0.6999 1202 | vn -0.5958 0.3939 -0.6999 1203 | vn -0.3777 0.5188 -0.7669 1204 | vn 0.2579 0.6227 -0.7387 1205 | vn 0.6339 0.0997 -0.7669 1206 | vn 0.3683 0.8891 -0.2718 1207 | vn -0.0997 -0.6339 -0.7669 1208 | vn -0.6227 -0.2579 -0.7387 1209 | vn -0.5188 0.3777 -0.7669 1210 | vn -0.8891 -0.3683 -0.2718 1211 | vn 0.3939 0.5958 -0.6999 1212 | vn 0.0000 0.8165 -0.5773 1213 | vn 0.0000 0.9897 -0.1428 1214 | vn -0.3939 0.5958 -0.6999 1215 | vn 0.6999 0.6999 -0.1428 1216 | vn 0.5773 0.5773 -0.5773 1217 | vn 0.1428 0.6999 -0.6999 1218 | vn 0.6999 0.1428 -0.6999 1219 | vn -0.6998 -0.6998 -0.1435 1220 | vn -0.5650 -0.5650 -0.6012 1221 | vn -0.4820 -0.5001 -0.7194 1222 | vn -0.5001 -0.4820 -0.7194 1223 | usemtl Material.001 1224 | s 1 1225 | f 22/1/1 337/2/2 359/3/3 3/4/4 1226 | f 36/5/5 323/6/6 316/7/7 45/8/8 1227 | f 9/9/9 353/10/10 346/11/11 15/12/12 1228 | f 50/13/13 309/14/14 331/15/15 29/16/16 1229 | f 65/17/17 297/18/18 288/19/3 73/20/4 1230 | f 79/21/19 282/22/20 303/23/21 59/24/22 1231 | f 157/25/23 163/26/24 170/27/25 177/28/26 1232 | f 99/29/27 260/30/28 276/31/29 87/32/30 1233 | f 108/33/31 115/34/32 121/35/33 129/36/34 1234 | f 128/37/35 233/38/36 254/39/37 106/40/38 1235 | f 134/41/39 226/42/40 220/43/15 141/44/16 1236 | f 149/45/41 213/46/42 227/47/43 136/48/44 1237 | f 85/49/45 275/50/46 268/51/47 94/52/48 1238 | f 176/53/49 183/54/50 205/55/15 155/56/16 1239 | f 107/57/51 253/58/52 248/59/53 113/60/54 1240 | f 58/61/25 66/62/33 72/63/55 80/64/56 1241 | f 43/65/27 318/66/28 310/67/57 52/68/58 1242 | f 156/69/59 204/70/60 197/71/61 164/72/62 1243 | f 142/73/59 219/74/60 211/75/11 148/76/12 1244 | f 92/77/9 267/78/10 261/79/7 101/80/8 1245 | f 57/81/63 302/82/64 295/83/65 64/84/66 1246 | f 31/85/23 37/86/67 44/87/68 51/88/69 1247 | f 1/89/70 358/90/71 351/91/47 8/92/48 1248 | f 114/93/1 247/94/2 240/95/65 122/96/66 1249 | f 86/97/72 93/98/73 100/99/68 1250 | f 162/100/74 199/101/75 190/102/21 171/103/22 1251 | f 30/104/59 330/105/60 324/106/76 38/107/77 1252 | f 135/108/78 143/109/23 150/110/79 1253 | f 206/111/80 185/112/81 191/113/82 198/114/83 1254 | f 120/115/17 239/116/18 234/117/84 127/118/85 1255 | f 71/119/70 290/120/71 283/121/86 78/122/87 1256 | f 169/123/63 192/124/64 184/125/88 178/126/89 1257 | f 16/127/41 345/128/42 338/129/53 24/130/54 1258 | f 255/131/90 232/132/91 241/133/92 246/134/93 1259 | f 225/135/94 212/136/95 218/137/80 1260 | f 274/138/96 262/139/97 269/140/98 1261 | f 332/141/80 311/142/99 317/143/97 325/144/100 1262 | f 304/145/82 281/146/101 289/147/102 296/148/92 1263 | f 360/149/102 339/150/93 344/151/95 352/152/98 1264 | f 1/89/70 4/153/103 5/154/104 7/155/105 1265 | f 2/156/55 6/157/106 5/158/104 4/159/103 1266 | f 3/4/4 7/160/105 5/161/104 6/162/106 1267 | f 8/92/48 11/163/107 12/164/108 14/165/109 1268 | f 9/9/9 13/166/110 12/167/108 11/168/107 1269 | f 10/169/73 14/170/109 12/171/108 13/172/110 1270 | f 15/12/12 18/173/111 19/174/112 21/175/113 1271 | f 16/127/41 20/176/114 19/177/112 18/178/111 1272 | f 17/179/79 21/180/113 19/181/112 20/182/114 1273 | f 22/1/1 25/183/115 26/184/116 28/185/117 1274 | f 23/186/32 27/187/118 26/188/116 25/189/115 1275 | f 24/130/54 28/190/117 26/191/116 27/192/118 1276 | f 29/16/16 32/193/119 33/194/120 35/195/121 1277 | f 30/104/59 34/196/122 33/197/120 32/198/119 1278 | f 31/85/23 35/199/121 33/200/120 34/201/122 1279 | f 36/5/5 39/202/123 40/203/124 42/204/125 1280 | f 37/86/67 41/205/126 40/206/124 39/207/123 1281 | f 38/107/77 42/204/125 40/208/124 41/209/126 1282 | f 43/65/27 46/210/127 47/211/128 49/212/129 1283 | f 44/87/68 48/213/130 47/214/128 46/215/127 1284 | f 45/8/8 49/216/129 47/217/128 48/218/130 1285 | f 50/13/13 53/219/131 54/220/132 56/221/133 1286 | f 51/88/69 55/222/134 54/223/132 53/224/131 1287 | f 52/68/58 56/225/133 54/226/132 55/227/134 1288 | f 57/81/63 60/228/135 61/229/136 63/230/137 1289 | f 58/61/25 62/231/138 61/232/136 60/233/135 1290 | f 59/24/22 63/234/137 61/235/136 62/236/138 1291 | f 64/84/66 67/237/139 68/238/140 70/239/141 1292 | f 65/17/17 69/240/142 68/241/140 67/237/139 1293 | f 66/62/33 70/242/141 68/243/140 69/244/142 1294 | f 71/119/70 74/245/103 75/246/104 77/247/105 1295 | f 72/63/55 76/248/106 75/249/104 74/250/103 1296 | f 73/20/4 77/251/105 75/252/104 76/253/106 1297 | f 78/122/87 81/254/143 82/255/144 84/256/145 1298 | f 79/21/19 83/257/146 82/258/144 81/259/143 1299 | f 80/64/56 84/260/145 82/261/144 83/262/146 1300 | f 85/49/45 88/263/147 89/264/148 91/265/149 1301 | f 86/97/72 90/266/150 89/267/148 88/268/147 1302 | f 87/32/30 91/269/149 89/270/148 90/271/150 1303 | f 92/77/9 95/272/110 96/273/108 98/274/107 1304 | f 93/98/73 97/275/109 96/276/108 95/277/110 1305 | f 94/52/48 98/278/107 96/279/108 97/280/109 1306 | f 99/29/27 102/281/127 103/282/128 105/283/129 1307 | f 100/99/68 104/284/130 103/285/128 102/286/127 1308 | f 101/80/8 105/287/129 103/288/128 104/289/130 1309 | f 106/40/38 109/290/151 110/291/152 112/292/153 1310 | f 107/57/51 111/293/154 110/294/152 109/295/151 1311 | f 108/33/31 112/296/153 110/297/152 111/298/154 1312 | f 113/60/54 116/299/117 117/300/116 119/301/118 1313 | f 114/93/1 118/302/115 117/303/116 116/304/117 1314 | f 115/34/32 119/305/118 117/306/116 118/307/115 1315 | f 120/115/17 123/308/142 124/309/140 126/310/139 1316 | f 121/35/33 125/311/141 124/312/140 123/313/142 1317 | f 122/96/66 126/310/139 124/314/140 125/315/141 1318 | f 127/118/85 130/316/155 131/317/156 133/318/157 1319 | f 128/37/35 132/319/158 131/320/156 130/321/155 1320 | f 129/36/34 133/322/157 131/323/156 132/324/158 1321 | f 134/41/39 137/325/159 138/326/160 140/327/161 1322 | f 135/108/78 139/328/162 138/329/160 137/330/159 1323 | f 136/48/44 140/331/161 138/332/160 139/333/162 1324 | f 141/44/16 144/334/119 145/335/120 147/336/121 1325 | f 142/73/59 146/337/122 145/338/120 144/339/119 1326 | f 143/109/23 147/340/121 145/341/120 146/342/122 1327 | f 148/76/12 151/343/111 152/344/112 154/345/113 1328 | f 149/45/41 153/346/114 152/347/112 151/348/111 1329 | f 150/110/79 154/349/113 152/350/112 153/351/114 1330 | f 155/56/16 158/352/119 159/353/120 161/354/121 1331 | f 156/69/59 160/355/122 159/356/120 158/357/119 1332 | f 157/25/23 161/358/121 159/359/120 160/360/122 1333 | f 162/100/74 165/361/163 166/362/164 168/363/165 1334 | f 163/26/24 167/364/166 166/365/164 165/366/163 1335 | f 164/72/62 168/367/165 166/368/164 167/369/166 1336 | f 169/123/63 172/370/135 173/371/136 175/372/137 1337 | f 170/27/25 174/373/138 173/374/136 172/375/135 1338 | f 171/103/22 175/376/137 173/377/136 174/378/138 1339 | f 176/53/49 179/379/167 180/380/168 182/381/169 1340 | f 177/28/26 181/382/170 180/383/168 179/384/167 1341 | f 178/126/89 182/381/169 180/385/168 181/386/170 1342 | f 183/54/50 186/387/171 187/388/172 189/389/173 1343 | f 184/125/88 188/390/174 187/391/172 186/387/171 1344 | f 185/112/81 189/392/173 187/393/172 188/394/174 1345 | f 190/102/21 193/395/175 194/396/176 196/397/177 1346 | f 191/113/82 195/398/178 194/399/176 193/400/175 1347 | f 192/124/64 196/401/177 194/402/176 195/403/178 1348 | f 197/71/61 200/404/179 201/405/180 203/406/181 1349 | f 198/114/83 202/407/182 201/408/180 200/409/179 1350 | f 199/101/75 203/410/181 201/411/180 202/412/182 1351 | f 204/70/60 207/413/183 208/414/184 210/415/185 1352 | f 205/55/15 209/416/186 208/417/184 207/418/183 1353 | f 206/111/80 210/419/185 208/420/184 209/421/186 1354 | f 211/75/11 214/422/187 215/423/188 217/424/189 1355 | f 212/136/95 216/425/190 215/426/188 214/427/187 1356 | f 213/46/42 217/428/189 215/429/188 216/430/190 1357 | f 218/137/80 221/431/185 222/432/184 224/433/186 1358 | f 219/74/60 223/434/183 222/435/184 221/436/185 1359 | f 220/43/15 224/437/186 222/438/184 223/439/183 1360 | f 225/135/94 228/440/191 229/441/192 231/442/193 1361 | f 226/42/40 230/443/194 229/444/192 228/445/191 1362 | f 227/47/43 231/446/193 229/447/192 230/448/194 1363 | f 232/132/91 235/449/195 236/450/196 238/451/197 1364 | f 233/38/36 237/452/198 236/453/196 235/454/195 1365 | f 234/117/84 238/455/197 236/456/196 237/457/198 1366 | f 239/116/18 242/458/199 243/459/200 245/460/201 1367 | f 240/95/65 244/461/202 243/462/200 242/458/199 1368 | f 241/133/92 245/463/201 243/464/200 244/465/202 1369 | f 246/134/93 249/466/203 250/467/204 252/468/205 1370 | f 247/94/2 251/469/206 250/470/204 249/471/203 1371 | f 248/59/53 252/472/205 250/473/204 251/474/206 1372 | f 253/58/52 256/475/207 257/476/208 259/477/209 1373 | f 254/39/37 258/478/210 257/479/208 256/480/207 1374 | f 255/131/90 259/481/209 257/482/208 258/483/210 1375 | f 260/30/28 263/484/211 264/485/212 266/486/213 1376 | f 261/79/7 265/487/214 264/488/212 263/489/211 1377 | f 262/139/97 266/490/213 264/491/212 265/492/214 1378 | f 267/78/10 270/493/215 271/494/216 273/495/217 1379 | f 268/51/47 272/496/218 271/497/216 270/498/215 1380 | f 269/140/98 273/499/217 271/500/216 272/501/218 1381 | f 274/138/96 277/502/219 278/503/220 280/504/221 1382 | f 275/50/46 279/505/222 278/506/220 277/507/219 1383 | f 276/31/29 280/508/221 278/509/220 279/510/222 1384 | f 281/146/101 284/511/223 285/512/224 287/513/225 1385 | f 282/22/20 286/514/226 285/515/224 284/516/223 1386 | f 283/121/86 287/517/225 285/518/224 286/519/226 1387 | f 288/19/3 291/520/227 292/521/228 294/522/229 1388 | f 289/147/102 293/523/230 292/524/228 291/525/227 1389 | f 290/120/71 294/526/229 292/527/228 293/528/230 1390 | f 295/83/65 298/529/202 299/530/200 301/531/199 1391 | f 296/148/92 300/532/201 299/533/200 298/534/202 1392 | f 297/18/18 301/531/199 299/535/200 300/536/201 1393 | f 302/82/64 305/537/177 306/538/176 308/539/178 1394 | f 303/23/21 307/540/175 306/541/176 305/542/177 1395 | f 304/145/82 308/543/178 306/544/176 307/545/175 1396 | f 309/14/14 312/546/231 313/547/232 315/548/233 1397 | f 310/67/57 314/549/234 313/550/232 312/551/231 1398 | f 311/142/99 315/552/233 313/553/232 314/554/234 1399 | f 316/7/7 319/555/214 320/556/212 322/557/211 1400 | f 317/143/97 321/558/213 320/559/212 319/560/214 1401 | f 318/66/28 322/561/211 320/562/212 321/563/213 1402 | f 323/6/6 326/564/235 327/565/236 329/566/237 1403 | f 324/106/76 328/567/238 327/568/236 326/564/235 1404 | f 325/144/100 329/569/237 327/570/236 328/571/238 1405 | f 330/105/60 333/572/183 334/573/184 336/574/185 1406 | f 331/15/15 335/575/186 334/576/184 333/577/183 1407 | f 332/141/80 336/578/185 334/579/184 335/580/186 1408 | f 337/2/2 340/581/206 341/582/204 343/583/203 1409 | f 338/129/53 342/584/205 341/585/204 340/586/206 1410 | f 339/150/93 343/587/203 341/588/204 342/589/205 1411 | f 344/151/95 347/590/190 348/591/188 350/592/187 1412 | f 345/128/42 349/593/189 348/594/188 347/595/190 1413 | f 346/11/11 350/596/187 348/597/188 349/598/189 1414 | f 351/91/47 354/599/218 355/600/216 357/601/215 1415 | f 352/152/98 356/602/217 355/603/216 354/604/218 1416 | f 353/10/10 357/605/215 355/606/216 356/607/217 1417 | f 358/90/71 361/608/229 362/609/228 364/610/230 1418 | f 359/3/3 363/611/227 362/612/228 361/613/229 1419 | f 360/149/102 364/614/230 362/615/228 363/616/227 1420 | f 101/80/8 261/79/7 263/489/211 105/287/129 1421 | f 105/283/129 263/484/211 260/30/28 99/29/27 1422 | f 52/68/58 310/67/57 312/551/231 56/225/133 1423 | f 56/221/133 312/546/231 309/14/14 50/13/13 1424 | f 94/52/48 268/51/47 270/498/215 98/278/107 1425 | f 98/274/107 270/493/215 267/78/10 92/77/9 1426 | f 45/8/8 316/7/7 322/557/211 49/216/129 1427 | f 49/212/129 322/561/211 318/66/28 43/65/27 1428 | f 38/107/77 324/106/76 326/564/235 42/204/125 1429 | f 42/204/125 326/564/235 323/6/6 36/5/5 1430 | f 330/105/60 30/104/59 32/198/119 333/572/183 1431 | f 333/577/183 32/193/119 29/16/16 331/15/15 1432 | f 155/56/16 205/55/15 207/418/183 158/352/119 1433 | f 158/357/119 207/413/183 204/70/60 156/69/59 1434 | f 106/40/38 254/39/37 256/480/207 109/290/151 1435 | f 109/295/151 256/475/207 253/58/52 107/57/51 1436 | f 178/126/89 184/125/88 186/387/171 182/381/169 1437 | f 182/381/169 186/387/171 183/54/50 176/53/49 1438 | f 24/130/54 338/129/53 340/586/206 28/190/117 1439 | f 28/185/117 340/581/206 337/2/2 22/1/1 1440 | f 122/96/66 240/95/65 242/458/199 126/310/139 1441 | f 126/310/139 242/458/199 239/116/18 120/115/17 1442 | f 73/20/4 288/19/3 294/522/229 77/251/105 1443 | f 77/247/105 294/526/229 290/120/71 71/119/70 1444 | f 171/103/22 190/102/21 196/397/177 175/376/137 1445 | f 175/372/137 196/401/177 192/124/64 169/123/63 1446 | f 199/101/75 162/100/74 168/363/165 203/410/181 1447 | f 203/406/181 168/367/165 164/72/62 197/71/61 1448 | f 184/125/88 192/124/64 195/403/178 188/390/174 1449 | f 188/394/174 195/398/178 191/113/82 185/112/81 1450 | f 211/75/11 219/74/60 221/436/185 214/422/187 1451 | f 214/427/187 221/431/185 218/137/80 212/136/95 1452 | f 227/47/43 213/46/42 216/430/190 231/446/193 1453 | f 231/442/193 216/425/190 212/136/95 225/135/94 1454 | f 240/95/65 247/94/2 249/471/203 244/461/202 1455 | f 244/465/202 249/466/203 246/134/93 241/133/92 1456 | f 254/39/37 233/38/36 235/454/195 258/478/210 1457 | f 258/483/210 235/449/195 232/132/91 255/131/90 1458 | f 268/51/47 275/50/46 277/507/219 272/496/218 1459 | f 272/501/218 277/502/219 274/138/96 269/140/98 1460 | f 261/79/7 267/78/10 273/495/217 265/487/214 1461 | f 265/492/214 273/499/217 269/140/98 262/139/97 1462 | f 283/121/86 290/120/71 293/528/230 287/517/225 1463 | f 287/513/225 293/523/230 289/147/102 281/146/101 1464 | f 310/67/57 318/66/28 321/563/213 314/549/234 1465 | f 314/554/234 321/558/213 317/143/97 311/142/99 1466 | f 331/15/15 309/14/14 315/548/233 335/575/186 1467 | f 335/580/186 315/552/233 311/142/99 332/141/80 1468 | f 338/129/53 345/128/42 347/595/190 342/584/205 1469 | f 342/589/205 347/590/190 344/151/95 339/150/93 1470 | f 324/106/76 330/105/60 336/574/185 328/567/238 1471 | f 328/571/238 336/578/185 332/141/80 325/144/100 1472 | f 10/169/73 2/156/55 4/159/103 14/170/109 1473 | f 14/165/109 4/153/103 1/89/70 8/92/48 1474 | f 17/179/79 10/169/73 13/172/110 21/180/113 1475 | f 21/175/113 13/166/110 9/9/9 15/12/12 1476 | f 23/186/32 17/179/79 20/182/114 27/187/118 1477 | f 27/192/118 20/176/114 16/127/41 24/130/54 1478 | f 2/156/55 23/186/32 25/189/115 6/157/106 1479 | f 6/162/106 25/183/115 22/1/1 3/4/4 1480 | f 37/86/67 31/85/23 34/201/122 41/205/126 1481 | f 41/209/126 34/196/122 30/104/59 38/107/77 1482 | f 44/87/68 37/86/67 39/207/123 48/213/130 1483 | f 48/218/130 39/202/123 36/5/5 45/8/8 1484 | f 51/88/69 44/87/68 46/215/127 55/222/134 1485 | f 55/227/134 46/210/127 43/65/27 52/68/58 1486 | f 31/85/23 51/88/69 53/224/131 35/199/121 1487 | f 35/195/121 53/219/131 50/13/13 29/16/16 1488 | f 66/62/33 58/61/25 60/233/135 70/242/141 1489 | f 70/239/141 60/228/135 57/81/63 64/84/66 1490 | f 72/63/55 66/62/33 69/244/142 76/248/106 1491 | f 76/253/106 69/240/142 65/17/17 73/20/4 1492 | f 80/64/56 72/63/55 74/250/103 84/260/145 1493 | f 84/256/145 74/245/103 71/119/70 78/122/87 1494 | f 58/61/25 80/64/56 83/262/146 62/231/138 1495 | f 62/236/138 83/257/146 79/21/19 59/24/22 1496 | f 93/98/73 86/97/72 88/268/147 97/275/109 1497 | f 97/280/109 88/263/147 85/49/45 94/52/48 1498 | f 100/99/68 93/98/73 95/277/110 104/284/130 1499 | f 104/289/130 95/272/110 92/77/9 101/80/8 1500 | f 86/97/72 100/99/68 102/286/127 90/266/150 1501 | f 90/271/150 102/281/127 99/29/27 87/32/30 1502 | f 115/34/32 108/33/31 111/298/154 119/305/118 1503 | f 119/301/118 111/293/154 107/57/51 113/60/54 1504 | f 121/35/33 115/34/32 118/307/115 125/311/141 1505 | f 125/315/141 118/302/115 114/93/1 122/96/66 1506 | f 129/36/34 121/35/33 123/313/142 133/322/157 1507 | f 133/318/157 123/308/142 120/115/17 127/118/85 1508 | f 108/33/31 129/36/34 132/324/158 112/296/153 1509 | f 112/292/153 132/319/158 128/37/35 106/40/38 1510 | f 143/109/23 135/108/78 137/330/159 147/340/121 1511 | f 147/336/121 137/325/159 134/41/39 141/44/16 1512 | f 150/110/79 143/109/23 146/342/122 154/349/113 1513 | f 154/345/113 146/337/122 142/73/59 148/76/12 1514 | f 135/108/78 150/110/79 153/351/114 139/328/162 1515 | f 139/333/162 153/346/114 149/45/41 136/48/44 1516 | f 163/26/24 157/25/23 160/360/122 167/364/166 1517 | f 167/369/166 160/355/122 156/69/59 164/72/62 1518 | f 170/27/25 163/26/24 165/366/163 174/373/138 1519 | f 174/378/138 165/361/163 162/100/74 171/103/22 1520 | f 177/28/26 170/27/25 172/375/135 181/382/170 1521 | f 181/386/170 172/370/135 169/123/63 178/126/89 1522 | f 157/25/23 177/28/26 179/384/167 161/358/121 1523 | f 161/354/121 179/379/167 176/53/49 155/56/16 1524 | f 148/76/12 211/75/11 217/424/189 151/343/111 1525 | f 151/348/111 217/428/189 213/46/42 149/45/41 1526 | f 275/50/46 85/49/45 91/265/149 279/505/222 1527 | f 279/510/222 91/269/149 87/32/30 276/31/29 1528 | f 226/42/40 134/41/39 140/327/161 230/443/194 1529 | f 230/448/194 140/331/161 136/48/44 227/47/43 1530 | f 141/44/16 220/43/15 223/439/183 144/334/119 1531 | f 144/339/119 223/434/183 219/74/60 142/73/59 1532 | f 59/24/22 303/23/21 305/542/177 63/234/137 1533 | f 63/230/137 305/537/177 302/82/64 57/81/63 1534 | f 3/4/4 359/3/3 361/613/229 7/160/105 1535 | f 7/155/105 361/608/229 358/90/71 1/89/70 1536 | f 78/122/87 283/121/86 286/519/226 81/254/143 1537 | f 81/259/143 286/514/226 282/22/20 79/21/19 1538 | f 127/118/85 234/117/84 237/457/198 130/316/155 1539 | f 130/321/155 237/452/198 233/38/36 128/37/35 1540 | f 297/18/18 65/17/17 67/237/139 301/531/199 1541 | f 301/531/199 67/237/139 64/84/66 295/83/65 1542 | f 247/94/2 114/93/1 116/304/117 251/469/206 1543 | f 251/474/206 116/299/117 113/60/54 248/59/53 1544 | f 353/10/10 9/9/9 11/168/107 357/605/215 1545 | f 357/601/215 11/163/107 8/92/48 351/91/47 1546 | f 15/12/12 346/11/11 349/598/189 18/173/111 1547 | f 18/178/111 349/593/189 345/128/42 16/127/41 1548 | f 205/55/15 183/54/50 189/389/173 209/416/186 1549 | f 209/421/186 189/392/173 185/112/81 206/111/80 1550 | f 190/102/21 199/101/75 202/412/182 193/395/175 1551 | f 193/400/175 202/407/182 198/114/83 191/113/82 1552 | f 197/71/61 204/70/60 210/415/185 200/404/179 1553 | f 200/409/179 210/419/185 206/111/80 198/114/83 1554 | f 220/43/15 226/42/40 228/445/191 224/437/186 1555 | f 224/433/186 228/440/191 225/135/94 218/137/80 1556 | f 234/117/84 239/116/18 245/460/201 238/455/197 1557 | f 238/451/197 245/463/201 241/133/92 232/132/91 1558 | f 248/59/53 253/58/52 259/477/209 252/472/205 1559 | f 252/468/205 259/481/209 255/131/90 246/134/93 1560 | f 276/31/29 260/30/28 266/486/213 280/508/221 1561 | f 280/504/221 266/490/213 262/139/97 274/138/96 1562 | f 303/23/21 282/22/20 284/516/223 307/540/175 1563 | f 307/545/175 284/511/223 281/146/101 304/145/82 1564 | f 288/19/3 297/18/18 300/536/201 291/520/227 1565 | f 291/525/227 300/532/201 296/148/92 289/147/102 1566 | f 295/83/65 302/82/64 308/539/178 298/529/202 1567 | f 298/534/202 308/543/178 304/145/82 296/148/92 1568 | f 316/7/7 323/6/6 329/566/237 319/555/214 1569 | f 319/560/214 329/569/237 325/144/100 317/143/97 1570 | f 359/3/3 337/2/2 343/583/203 363/611/227 1571 | f 363/616/227 343/587/203 339/150/93 360/149/102 1572 | f 346/11/11 353/10/10 356/607/217 350/596/187 1573 | f 350/592/187 356/602/217 352/152/98 344/151/95 1574 | f 351/91/47 358/90/71 364/610/230 354/599/218 1575 | f 354/604/218 364/614/230 360/149/102 352/152/98 1576 | f 2/156/55 10/169/73 17/179/79 23/186/32 1577 | -------------------------------------------------------------------------------- /examples/meshes/suzanneNoUV.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.78 (sub 0) OBJ File: 'elmLogo.blend' 2 | # www.blender.org 3 | o Suzanne_Suzanne.001 4 | v 1.256235 1.096088 0.351251 5 | v 0.743765 1.096088 0.351251 6 | v 1.292840 1.054907 0.305495 7 | v 0.707160 1.054907 0.305495 8 | v 1.320294 1.032029 0.241436 9 | v 0.679706 1.032029 0.241436 10 | v 1.205903 0.986273 0.264314 11 | v 0.794097 0.986273 0.264314 12 | v 1.205903 1.018302 0.323797 13 | v 0.794097 1.018302 0.323797 14 | v 1.205903 1.077785 0.360402 15 | v 0.794097 1.077785 0.360402 16 | v 1.160147 1.096088 0.369554 17 | v 0.839853 1.096088 0.369554 18 | v 1.118966 1.054907 0.337524 19 | v 0.881034 1.054907 0.337524 20 | v 1.091512 1.032029 0.282617 21 | v 0.908487 1.032029 0.282617 22 | v 1.045756 1.141844 0.287192 23 | v 0.954244 1.141844 0.287192 24 | v 1.082361 1.141844 0.337524 25 | v 0.917639 1.141844 0.337524 26 | v 1.141844 1.141844 0.369554 27 | v 0.858155 1.141844 0.369554 28 | v 1.160147 1.192176 0.369554 29 | v 0.839853 1.192176 0.369554 30 | v 1.118966 1.228781 0.337524 31 | v 0.881034 1.228781 0.337524 32 | v 1.091512 1.256235 0.282617 33 | v 0.908487 1.256235 0.282617 34 | v 1.205903 1.301991 0.264314 35 | v 0.794097 1.301991 0.264314 36 | v 1.205903 1.265386 0.323797 37 | v 0.794097 1.265386 0.323797 38 | v 1.205903 1.210479 0.360402 39 | v 0.794097 1.210479 0.360402 40 | v 1.256235 1.192176 0.351251 41 | v 0.743765 1.192176 0.351251 42 | v 1.292840 1.228781 0.305495 43 | v 0.707160 1.228781 0.305495 44 | v 1.320294 1.256235 0.241436 45 | v 0.679706 1.256235 0.241436 46 | v 1.366050 1.141844 0.232285 47 | v 0.633950 1.141844 0.232285 48 | v 1.329445 1.141844 0.296344 49 | v 0.670555 1.141844 0.296344 50 | v 1.274537 1.141844 0.346675 51 | v 0.725462 1.141844 0.346675 52 | v 1.279113 1.141844 0.355827 53 | v 0.720887 1.141844 0.355827 54 | v 1.260810 1.196752 0.360402 55 | v 0.739189 1.196752 0.360402 56 | v 1.205903 1.219630 0.374129 57 | v 0.794097 1.219630 0.374129 58 | v 1.155571 1.196752 0.383280 59 | v 0.844429 1.196752 0.383280 60 | v 1.132693 1.141844 0.383280 61 | v 0.867307 1.141844 0.383280 62 | v 1.155571 1.091512 0.383280 63 | v 0.844429 1.091512 0.383280 64 | v 1.205903 1.141844 0.387856 65 | v 0.794097 1.141844 0.387856 66 | v 1.205903 1.068634 0.374129 67 | v 0.794097 1.068634 0.374129 68 | v 1.260810 1.091512 0.360402 69 | v 0.739189 1.091512 0.360402 70 | v 1.000000 1.251659 0.337524 71 | v 1.000000 1.205903 0.383280 72 | v 1.000000 0.601920 0.332949 73 | v 1.000000 0.812399 0.360402 74 | v 1.000000 0.890185 0.369554 75 | v 1.000000 0.547013 0.323797 76 | v 1.000000 1.237932 0.255163 77 | v 1.000000 1.334020 0.236860 78 | v 1.000000 1.526197 -0.417454 79 | v 1.000000 1.329445 -0.595903 80 | v 1.000000 1.041180 -0.582176 81 | v 1.000000 0.775794 -0.303063 82 | v 1.118966 0.890185 0.232285 83 | v 0.881034 0.890185 0.232285 84 | v 1.183025 0.743765 0.236860 85 | v 0.816975 0.743765 0.236860 86 | v 1.205903 0.592769 0.236860 87 | v 0.794097 0.592769 0.236860 88 | v 1.215054 0.478379 0.213982 89 | v 0.784945 0.478379 0.213982 90 | v 1.192176 0.446349 0.209407 91 | v 0.807824 0.446349 0.209407 92 | v 1.105239 0.432622 0.227709 93 | v 0.894760 0.432622 0.227709 94 | v 1.000000 0.423471 0.241436 95 | v 1.256235 0.917639 0.213982 96 | v 0.743765 0.917639 0.213982 97 | v 1.370625 0.977122 0.218558 98 | v 0.629374 0.977122 0.218558 99 | v 1.485016 1.086937 0.163650 100 | v 0.514984 1.086937 0.163650 101 | v 1.503319 1.251659 0.250587 102 | v 0.496681 1.251659 0.250587 103 | v 1.416382 1.283689 0.268890 104 | v 0.583618 1.283689 0.268890 105 | v 1.288264 1.352323 0.305495 106 | v 0.711735 1.352323 0.305495 107 | v 1.187600 1.443835 0.332949 108 | v 0.812399 1.443835 0.332949 109 | v 1.091512 1.420957 0.346675 110 | v 0.908487 1.420957 0.346675 111 | v 1.036605 1.288264 0.342100 112 | v 0.963395 1.288264 0.342100 113 | v 1.096088 1.242508 0.355827 114 | v 0.903912 1.242508 0.355827 115 | v 1.073210 1.178449 0.351251 116 | v 0.926790 1.178449 0.351251 117 | v 1.118966 1.054907 0.337524 118 | v 0.881034 1.054907 0.337524 119 | v 1.219630 1.009151 0.314646 120 | v 0.780370 1.009151 0.314646 121 | v 1.288264 1.036605 0.296344 122 | v 0.711735 1.036605 0.296344 123 | v 1.366050 1.109815 0.282617 124 | v 0.633950 1.109815 0.282617 125 | v 1.375201 1.173874 0.282617 126 | v 0.624799 1.173874 0.282617 127 | v 1.352323 1.219630 0.291768 128 | v 0.647677 1.219630 0.291768 129 | v 1.251659 1.256235 0.323797 130 | v 0.748340 1.256235 0.323797 131 | v 1.146420 1.274537 0.346675 132 | v 0.853580 1.274537 0.346675 133 | v 1.000000 0.551589 0.332949 134 | v 1.064059 0.579042 0.332949 135 | v 0.935941 0.579042 0.332949 136 | v 1.068634 0.510408 0.319222 137 | v 0.931365 0.510408 0.319222 138 | v 1.036605 0.482954 0.310070 139 | v 0.963395 0.482954 0.310070 140 | v 1.000000 0.478379 0.305495 141 | v 1.000000 0.885609 0.342100 142 | v 1.000000 0.917639 0.337524 143 | v 1.059483 0.913063 0.337524 144 | v 0.940517 0.913063 0.337524 145 | v 1.073210 0.867307 0.342100 146 | v 0.926790 0.867307 0.342100 147 | v 1.050332 0.830702 0.337524 148 | v 0.949668 0.830702 0.337524 149 | v 1.233357 0.972546 0.296344 150 | v 0.766643 0.972546 0.296344 151 | v 1.361474 1.032029 0.268890 152 | v 0.638525 1.032029 0.268890 153 | v 1.425533 1.118966 0.255163 154 | v 0.574467 1.118966 0.255163 155 | v 1.434684 1.219630 0.287192 156 | v 0.565316 1.219630 0.287192 157 | v 1.402655 1.242508 0.328373 158 | v 0.597345 1.242508 0.328373 159 | v 1.256235 1.320294 0.369554 160 | v 0.743765 1.320294 0.369554 161 | v 1.183025 1.375201 0.392432 162 | v 0.816975 1.375201 0.392432 163 | v 1.118966 1.361474 0.401583 164 | v 0.881034 1.361474 0.401583 165 | v 1.059483 1.251659 0.397007 166 | v 0.940517 1.251659 0.397007 167 | v 1.073210 0.940517 0.378705 168 | v 0.926790 0.940517 0.378705 169 | v 1.123542 0.739189 0.319222 170 | v 0.876458 0.739189 0.319222 171 | v 1.146420 0.588194 0.305495 172 | v 0.853580 0.588194 0.305495 173 | v 1.155571 0.519559 0.291768 174 | v 0.844429 0.519559 0.291768 175 | v 1.137269 0.464652 0.273465 176 | v 0.862731 0.464652 0.273465 177 | v 1.096088 0.455501 0.273465 178 | v 0.903912 0.455501 0.273465 179 | v 1.000000 0.446349 0.278041 180 | v 1.000000 1.027454 0.328373 181 | v 1.000000 1.123542 0.351251 182 | v 1.192176 1.279113 0.337524 183 | v 0.807824 1.279113 0.337524 184 | v 1.096088 1.082361 0.342100 185 | v 0.903912 1.082361 0.342100 186 | v 1.077785 1.123542 0.346675 187 | v 0.922214 1.123542 0.346675 188 | v 1.068634 0.597345 0.332949 189 | v 0.931365 0.597345 0.332949 190 | v 1.045756 0.739189 0.342100 191 | v 0.954244 0.739189 0.342100 192 | v 1.000000 0.739189 0.342100 193 | v 1.000000 0.807824 0.337524 194 | v 1.054907 0.839853 0.360402 195 | v 0.945092 0.839853 0.360402 196 | v 1.077785 0.867307 0.369554 197 | v 0.922214 0.867307 0.369554 198 | v 1.064059 0.922214 0.360402 199 | v 0.935941 0.922214 0.360402 200 | v 1.022878 0.926790 0.360402 201 | v 0.977122 0.926790 0.360402 202 | v 1.000000 0.881034 0.387856 203 | v 1.027454 0.913063 0.378705 204 | v 0.972546 0.913063 0.378705 205 | v 1.054907 0.908487 0.378705 206 | v 0.945092 0.908487 0.378705 207 | v 1.064059 0.867307 0.387856 208 | v 0.935941 0.867307 0.387856 209 | v 1.045756 0.853580 0.374129 210 | v 0.954244 0.853580 0.374129 211 | v 1.000000 0.830702 0.374129 212 | v 1.150995 0.816975 0.227709 213 | v 0.849004 0.816975 0.227709 214 | v 1.096088 0.858155 0.319222 215 | v 0.903912 0.858155 0.319222 216 | v 1.105239 0.816975 0.319222 217 | v 0.894760 0.816975 0.319222 218 | v 1.137269 0.853580 0.227709 219 | v 0.862731 0.853580 0.227709 220 | v 1.000000 0.487530 0.305495 221 | v 1.027454 0.492106 0.305495 222 | v 0.972546 0.492106 0.305495 223 | v 1.054907 0.519559 0.319222 224 | v 0.945092 0.519559 0.319222 225 | v 1.054907 0.565316 0.328373 226 | v 0.945092 0.565316 0.328373 227 | v 1.000000 0.542437 0.287192 228 | v 1.054907 0.560740 0.291768 229 | v 0.945092 0.560740 0.291768 230 | v 1.054907 0.524135 0.278041 231 | v 0.945092 0.524135 0.278041 232 | v 1.027454 0.501257 0.273465 233 | v 0.972546 0.501257 0.273465 234 | v 1.000000 0.496681 0.273465 235 | v 1.100664 1.128117 0.360402 236 | v 0.899336 1.128117 0.360402 237 | v 1.109815 1.091512 0.355827 238 | v 0.890185 1.091512 0.355827 239 | v 1.196752 1.251659 0.346675 240 | v 0.803248 1.251659 0.346675 241 | v 1.160147 1.247084 0.355827 242 | v 0.839853 1.247084 0.355827 243 | v 1.247084 1.233357 0.355827 244 | v 0.752916 1.233357 0.355827 245 | v 1.329445 1.205903 0.310070 246 | v 0.670555 1.205903 0.310070 247 | v 1.343172 1.169298 0.305495 248 | v 0.656828 1.169298 0.305495 249 | v 1.338596 1.114390 0.300919 250 | v 0.661404 1.114390 0.300919 251 | v 1.279113 1.059483 0.323797 252 | v 0.720887 1.059483 0.323797 253 | v 1.219630 1.036605 0.337524 254 | v 0.780370 1.036605 0.337524 255 | v 1.132693 1.064059 0.360402 256 | v 0.867307 1.064059 0.360402 257 | v 1.105239 1.173874 0.360402 258 | v 0.894760 1.173874 0.360402 259 | v 1.123542 1.219630 0.360402 260 | v 0.876458 1.219630 0.360402 261 | v 1.137269 1.210479 0.346675 262 | v 0.862731 1.210479 0.346675 263 | v 1.114390 1.173874 0.346675 264 | v 0.885609 1.173874 0.346675 265 | v 1.141844 1.073210 0.346675 266 | v 0.858155 1.073210 0.346675 267 | v 1.219630 1.050332 0.328373 268 | v 0.780370 1.050332 0.328373 269 | v 1.269962 1.068634 0.314646 270 | v 0.730038 1.068634 0.314646 271 | v 1.320294 1.123542 0.296344 272 | v 0.679706 1.123542 0.296344 273 | v 1.324869 1.164722 0.296344 274 | v 0.675130 1.164722 0.296344 275 | v 1.311142 1.196752 0.300919 276 | v 0.688857 1.196752 0.300919 277 | v 1.242508 1.228781 0.342100 278 | v 0.757492 1.228781 0.342100 279 | v 1.164722 1.233357 0.351251 280 | v 0.835277 1.233357 0.351251 281 | v 1.196752 1.237932 0.342100 282 | v 0.803248 1.237932 0.342100 283 | v 1.118966 1.100664 0.342100 284 | v 0.881034 1.100664 0.342100 285 | v 1.114390 1.132693 0.342100 286 | v 0.885609 1.132693 0.342100 287 | v 1.064059 1.269962 0.259739 288 | v 0.935941 1.269962 0.259739 289 | v 1.114390 1.388928 0.264314 290 | v 0.885609 1.388928 0.264314 291 | v 1.196752 1.402655 0.250587 292 | v 0.803248 1.402655 0.250587 293 | v 1.283689 1.324869 0.227709 294 | v 0.716311 1.324869 0.227709 295 | v 1.398079 1.265386 0.191104 296 | v 0.601920 1.265386 0.191104 297 | v 1.466714 1.237932 0.172802 298 | v 0.533286 1.237932 0.172802 299 | v 1.452987 1.096088 0.122470 300 | v 0.547013 1.096088 0.122470 301 | v 1.352323 1.000000 0.145348 302 | v 0.647677 1.000000 0.145348 303 | v 1.256235 0.945092 0.177377 304 | v 0.743765 0.945092 0.177377 305 | v 1.000000 1.526197 0.072138 306 | v 1.000000 1.576529 -0.142916 307 | v 1.000000 0.885609 -0.490664 308 | v 1.000000 0.730038 0.012655 309 | v 1.000000 0.428047 0.172802 310 | v 1.000000 0.528711 0.104167 311 | v 1.000000 0.665979 0.090441 312 | v 1.000000 0.716311 0.067562 313 | v 1.498743 1.137269 -0.065131 314 | v 0.501257 1.137269 -0.065131 315 | v 1.503319 1.187600 -0.124614 316 | v 0.496681 1.187600 -0.124614 317 | v 1.452987 1.155571 -0.353395 318 | v 0.547013 1.155571 -0.353395 319 | v 1.269962 1.256235 -0.508966 320 | v 0.730038 1.256235 -0.508966 321 | v 1.430109 0.972546 -0.055979 322 | v 0.569891 0.972546 -0.055979 323 | v 1.347747 0.926790 -0.193248 324 | v 0.652252 0.926790 -0.193248 325 | v 1.375201 0.995424 -0.348819 326 | v 0.624799 0.995424 -0.348819 327 | v 1.196752 1.032029 -0.486088 328 | v 0.803248 1.032029 -0.486088 329 | v 1.137269 0.794097 0.140772 330 | v 0.862731 0.794097 0.140772 331 | v 1.105239 0.757492 0.053836 332 | v 0.894760 0.757492 0.053836 333 | v 1.169298 0.583618 0.127046 334 | v 0.830702 0.583618 0.127046 335 | v 1.146420 0.707160 0.131621 336 | v 0.853580 0.707160 0.131621 337 | v 1.192176 0.464652 0.136197 338 | v 0.807824 0.464652 0.136197 339 | v 1.082361 0.556164 0.117894 340 | v 0.917639 0.556164 0.117894 341 | v 1.073210 0.684282 0.113319 342 | v 0.926790 0.684282 0.113319 343 | v 1.096088 0.446349 0.159075 344 | v 0.903912 0.446349 0.159075 345 | v 1.128117 0.835277 0.154499 346 | v 0.871882 0.835277 0.154499 347 | v 1.123542 0.867307 0.177377 348 | v 0.876458 0.867307 0.177377 349 | v 1.118966 0.899336 0.195680 350 | v 0.881034 0.899336 0.195680 351 | v 1.123542 0.771219 -0.001072 352 | v 0.876458 0.771219 -0.001072 353 | v 1.173874 0.816975 -0.252731 354 | v 0.826126 0.816975 -0.252731 355 | v 1.201327 0.913063 -0.412878 356 | v 0.798672 0.913063 -0.412878 357 | v 1.265386 1.507894 -0.321366 358 | v 0.734614 1.507894 -0.321366 359 | v 1.265386 1.544499 -0.138341 360 | v 0.734614 1.544499 -0.138341 361 | v 1.265386 1.498743 0.040109 362 | v 0.734614 1.498743 0.040109 363 | v 1.269962 1.306567 0.154499 364 | v 0.730038 1.306567 0.154499 365 | v 1.425533 1.237932 0.099592 366 | v 0.574467 1.237932 0.099592 367 | v 1.370625 1.265386 0.067562 368 | v 0.629374 1.265386 0.067562 369 | v 1.375201 1.411806 -0.065131 370 | v 0.624799 1.411806 -0.065131 371 | v 1.466714 1.329445 -0.023950 372 | v 0.533286 1.329445 -0.023950 373 | v 1.466714 1.361474 -0.165794 374 | v 0.533286 1.361474 -0.165794 375 | v 1.375201 1.439260 -0.211551 376 | v 0.624799 1.439260 -0.211551 377 | v 1.375201 1.398079 -0.357971 378 | v 0.624799 1.398079 -0.357971 379 | v 1.466714 1.315718 -0.307639 380 | v 0.533286 1.315718 -0.307639 381 | v 1.361474 1.192176 -0.440332 382 | v 0.638525 1.192176 -0.440332 383 | v 1.283689 1.013727 -0.417454 384 | v 0.716311 1.013727 -0.417454 385 | v 1.480440 1.192176 -0.216126 386 | v 0.519559 1.192176 -0.216126 387 | v 1.237932 0.899336 -0.010223 388 | v 0.762067 0.899336 -0.010223 389 | v 1.251659 0.885609 -0.220702 390 | v 0.748340 0.885609 -0.220702 391 | v 1.521621 1.237932 -0.234429 392 | v 0.478379 1.237932 -0.234429 393 | v 1.452987 0.917639 -0.170370 394 | v 0.547013 0.917639 -0.170370 395 | v 1.608558 0.940517 -0.289336 396 | v 0.391442 0.940517 -0.289336 397 | v 1.750402 1.032029 -0.348819 398 | v 0.249597 1.032029 -0.348819 399 | v 1.791583 1.187600 -0.344244 400 | v 0.208417 1.187600 -0.344244 401 | v 1.722949 1.297415 -0.344244 402 | v 0.277051 1.297415 -0.344244 403 | v 1.599407 1.279113 -0.280185 404 | v 0.400593 1.279113 -0.280185 405 | v 1.594831 1.242508 -0.266458 406 | v 0.405169 1.242508 -0.266458 407 | v 1.695495 1.256235 -0.325941 408 | v 0.304505 1.256235 -0.325941 409 | v 1.741251 1.169298 -0.335093 410 | v 0.258749 1.169298 -0.335093 411 | v 1.709222 1.045756 -0.335093 412 | v 0.290778 1.045756 -0.335093 413 | v 1.603982 0.977122 -0.275609 414 | v 0.396017 0.977122 -0.275609 415 | v 1.485016 0.958819 -0.174946 416 | v 0.514984 0.958819 -0.174946 417 | v 1.539924 1.210479 -0.225278 418 | v 0.460076 1.210479 -0.225278 419 | v 1.553650 1.178449 -0.266458 420 | v 0.446349 1.178449 -0.266458 421 | v 1.517045 0.986273 -0.220702 422 | v 0.482954 0.986273 -0.220702 423 | v 1.608558 1.000000 -0.312214 424 | v 0.391442 1.000000 -0.312214 425 | v 1.695495 1.054907 -0.357971 426 | v 0.304505 1.054907 -0.357971 427 | v 1.722949 1.146420 -0.357971 428 | v 0.277051 1.146420 -0.357971 429 | v 1.686344 1.210479 -0.353395 430 | v 0.313656 1.210479 -0.353395 431 | v 1.599407 1.201327 -0.307639 432 | v 0.400593 1.201327 -0.307639 433 | v 1.494167 1.169298 -0.220702 434 | v 0.505832 1.169298 -0.220702 435 | v 1.489592 1.100664 -0.257307 436 | v 0.510408 1.100664 -0.257307 437 | v 1.443835 1.054907 -0.257307 438 | v 0.556164 1.054907 -0.257307 439 | v 1.480440 1.050332 -0.257307 440 | v 0.519559 1.050332 -0.257307 441 | v 1.494167 1.009151 -0.257307 442 | v 0.505832 1.009151 -0.257307 443 | v 1.475865 0.990849 -0.257307 444 | v 0.524135 0.990849 -0.257307 445 | v 1.425533 1.000000 -0.138341 446 | v 0.574467 1.000000 -0.138341 447 | v 1.420957 0.986273 -0.197824 448 | v 0.579042 0.986273 -0.197824 449 | v 1.420957 1.022878 -0.206975 450 | v 0.579042 1.022878 -0.206975 451 | v 1.466714 1.118966 -0.220702 452 | v 0.533286 1.118966 -0.220702 453 | v 1.521621 1.141844 -0.252731 454 | v 0.478379 1.141844 -0.252731 455 | v 1.521621 1.137269 -0.284761 456 | v 0.478379 1.137269 -0.284761 457 | v 1.475865 0.990849 -0.284761 458 | v 0.524135 0.990849 -0.284761 459 | v 1.498743 1.009151 -0.284761 460 | v 0.501257 1.009151 -0.284761 461 | v 1.485016 1.045756 -0.284761 462 | v 0.514984 1.045756 -0.284761 463 | v 1.448411 1.054907 -0.284761 464 | v 0.551589 1.054907 -0.284761 465 | v 1.494167 1.100664 -0.284761 466 | v 0.505832 1.100664 -0.284761 467 | v 1.608558 1.192176 -0.339668 468 | v 0.391442 1.192176 -0.339668 469 | v 1.695495 1.201327 -0.380849 470 | v 0.304505 1.201327 -0.380849 471 | v 1.736676 1.141844 -0.385424 472 | v 0.263324 1.141844 -0.385424 473 | v 1.709222 1.050332 -0.380849 474 | v 0.290778 1.050332 -0.380849 475 | v 1.613134 1.000000 -0.344244 476 | v 0.386866 1.000000 -0.344244 477 | v 1.517045 0.990849 -0.252731 478 | v 0.482954 0.990849 -0.252731 479 | v 1.558226 1.169298 -0.298488 480 | v 0.441774 1.169298 -0.298488 481 | v 1.521621 1.064059 -0.289336 482 | v 0.478379 1.064059 -0.289336 483 | v 1.549075 1.036605 -0.293912 484 | v 0.450925 1.036605 -0.293912 485 | v 1.585680 1.073210 -0.312214 486 | v 0.414320 1.073210 -0.312214 487 | v 1.562802 1.100664 -0.303063 488 | v 0.437198 1.100664 -0.303063 489 | v 1.594831 1.137269 -0.316790 490 | v 0.405169 1.137269 -0.316790 491 | v 1.617709 1.109815 -0.321366 492 | v 0.382291 1.109815 -0.321366 493 | v 1.649739 1.123542 -0.325941 494 | v 0.350261 1.123542 -0.325941 495 | v 1.636012 1.160147 -0.325941 496 | v 0.363988 1.160147 -0.325941 497 | v 1.599407 1.256235 -0.380849 498 | v 0.400593 1.256235 -0.380849 499 | v 1.732100 1.274537 -0.417454 500 | v 0.267900 1.274537 -0.417454 501 | v 1.800734 1.173874 -0.390000 502 | v 0.199266 1.173874 -0.390000 503 | v 1.768705 1.032029 -0.408303 504 | v 0.231295 1.032029 -0.408303 505 | v 1.608558 0.949668 -0.385424 506 | v 0.391442 0.949668 -0.385424 507 | v 1.462138 0.926790 -0.289336 508 | v 0.537862 0.926790 -0.289336 509 | v 1.503319 1.224205 -0.321366 510 | v 0.496681 1.224205 -0.321366 511 | vn 0.9777 -0.0110 0.2097 512 | vn 0.7277 -0.6545 0.2051 513 | vn 0.6040 -0.5102 0.6122 514 | vn 0.8021 -0.0034 0.5972 515 | vn -0.6040 -0.5102 0.6122 516 | vn -0.7277 -0.6545 0.2051 517 | vn -0.9777 -0.0110 0.2097 518 | vn -0.8021 -0.0034 0.5972 519 | vn 0.6829 -0.5475 0.4835 520 | vn 0.8684 -0.0033 0.4958 521 | vn -0.6829 -0.5475 0.4835 522 | vn -0.8684 -0.0033 0.4958 523 | vn 0.0982 -0.7510 0.6530 524 | vn 0.1159 -0.8670 0.4847 525 | vn -0.1159 -0.8670 0.4847 526 | vn -0.0982 -0.7510 0.6530 527 | vn 0.0375 -0.9651 0.2592 528 | vn -0.0375 -0.9651 0.2592 529 | vn -0.6554 -0.6928 0.3008 530 | vn -0.4514 -0.5393 0.7109 531 | vn 0.4514 -0.5393 0.7109 532 | vn 0.6554 -0.6928 0.3008 533 | vn -0.5512 -0.6358 0.5402 534 | vn 0.5512 -0.6358 0.5402 535 | vn -0.6940 -0.0035 0.7199 536 | vn -0.8148 -0.0038 0.5797 537 | vn 0.8148 -0.0038 0.5797 538 | vn 0.6940 -0.0035 0.7199 539 | vn -0.9460 -0.0128 0.3237 540 | vn 0.9460 -0.0128 0.3237 541 | vn -0.6622 0.6914 0.2889 542 | vn -0.4551 0.5251 0.7191 543 | vn 0.4551 0.5251 0.7191 544 | vn 0.6622 0.6914 0.2889 545 | vn -0.5298 0.6266 0.5716 546 | vn 0.5298 0.6266 0.5716 547 | vn 0.1019 0.7401 0.6647 548 | vn 0.1224 0.8373 0.5328 549 | vn -0.1224 0.8373 0.5328 550 | vn -0.1019 0.7401 0.6647 551 | vn 0.0321 0.9710 0.2369 552 | vn -0.0321 0.9710 0.2369 553 | vn 0.7320 0.6527 0.1949 554 | vn 0.6084 0.4949 0.6203 555 | vn -0.6084 0.4949 0.6203 556 | vn -0.7320 0.6527 0.1949 557 | vn 0.6722 0.5381 0.5084 558 | vn -0.6722 0.5381 0.5084 559 | vn 0.7220 0.6499 0.2374 560 | vn 0.9737 -0.0122 0.2273 561 | vn -0.7220 0.6499 0.2374 562 | vn -0.9737 -0.0122 0.2273 563 | vn 0.0374 0.9336 0.3564 564 | vn -0.0374 0.9336 0.3564 565 | vn -0.6263 0.6470 0.4348 566 | vn 0.6263 0.6470 0.4348 567 | vn -0.9113 -0.0123 0.4116 568 | vn 0.9113 -0.0123 0.4116 569 | vn -0.6181 -0.6538 0.4364 570 | vn 0.6181 -0.6538 0.4364 571 | vn 0.0369 -0.9351 0.3524 572 | vn -0.0369 -0.9351 0.3524 573 | vn 0.7150 -0.6569 0.2391 574 | vn -0.7150 -0.6569 0.2391 575 | vn 0.1836 -0.0053 0.9830 576 | vn -0.1836 -0.0053 0.9830 577 | vn 0.1576 -0.9745 0.1596 578 | vn 0.1679 -0.7535 0.6356 579 | vn 0.0000 -0.7922 0.6102 580 | vn 0.0000 -0.9777 0.2098 581 | vn -0.1679 -0.7535 0.6356 582 | vn -0.1576 -0.9745 0.1596 583 | vn 0.6541 -0.7418 0.1480 584 | vn 0.3630 -0.6184 0.6970 585 | vn -0.3630 -0.6184 0.6970 586 | vn -0.6541 -0.7418 0.1480 587 | vn 0.9696 -0.1473 0.1954 588 | vn 0.5559 -0.2160 0.8027 589 | vn -0.5559 -0.2160 0.8027 590 | vn -0.9696 -0.1473 0.1954 591 | vn 0.9758 0.0949 0.1970 592 | vn 0.5678 -0.0330 0.8224 593 | vn -0.5678 -0.0330 0.8224 594 | vn -0.9758 0.0949 0.1970 595 | vn 0.9651 0.2189 0.1435 596 | vn 0.5872 0.1119 0.8016 597 | vn -0.5872 0.1119 0.8016 598 | vn -0.9651 0.2189 0.1435 599 | vn 0.9053 -0.3891 0.1703 600 | vn 0.3605 -0.9316 0.0454 601 | vn 0.3809 -0.5175 0.7662 602 | vn 0.0663 -0.1929 0.9789 603 | vn -0.3809 -0.5176 0.7662 604 | vn -0.3605 -0.9316 0.0454 605 | vn -0.9053 -0.3891 0.1703 606 | vn -0.0663 -0.1929 0.9789 607 | vn 0.5889 -0.7908 0.1668 608 | vn 0.4987 -0.4011 0.7683 609 | vn -0.4987 -0.4011 0.7683 610 | vn -0.5889 -0.7908 0.1668 611 | vn 0.9126 -0.4027 -0.0698 612 | vn 0.5489 -0.3266 0.7694 613 | vn -0.5489 -0.3266 0.7694 614 | vn -0.9126 -0.4027 -0.0698 615 | vn 0.8801 0.4238 0.2138 616 | vn 0.4875 -0.1470 0.8606 617 | vn -0.4875 -0.1470 0.8606 618 | vn -0.8801 0.4238 0.2138 619 | vn 0.5100 0.8330 0.2144 620 | vn 0.3417 -0.0325 0.9392 621 | vn -0.3417 -0.0325 0.9392 622 | vn -0.5100 0.8330 0.2144 623 | vn 0.5978 0.7838 0.1683 624 | vn 0.3141 -0.0304 0.9489 625 | vn -0.3141 -0.0304 0.9489 626 | vn -0.5978 0.7838 0.1683 627 | vn 0.2283 0.9588 0.1689 628 | vn 0.2711 0.2130 0.9387 629 | vn -0.2711 0.2130 0.9387 630 | vn -0.2283 0.9588 0.1689 631 | vn -0.5987 0.7773 0.1930 632 | vn -0.1643 0.1590 0.9735 633 | vn 0.1643 0.1590 0.9735 634 | vn 0.5987 0.7773 0.1930 635 | vn -0.7917 0.5829 0.1826 636 | vn -0.0729 -0.0287 0.9969 637 | vn 0.0729 -0.0287 0.9969 638 | vn 0.7917 0.5829 0.1826 639 | vn 0.0000 0.9595 0.2816 640 | vn 0.0000 -0.0241 0.9997 641 | vn 0.2654 -0.2040 0.9423 642 | vn 0.2660 -0.1257 0.9557 643 | vn -0.2660 -0.1257 0.9557 644 | vn -0.2654 -0.2040 0.9423 645 | vn 0.1334 -0.0975 0.9862 646 | vn -0.1334 -0.0975 0.9862 647 | vn 0.1978 -0.0104 0.9802 648 | vn -0.1978 -0.0104 0.9802 649 | vn 0.2413 -0.3067 0.9207 650 | vn -0.2413 -0.3067 0.9207 651 | vn 0.3630 -0.2123 0.9073 652 | vn -0.3630 -0.2123 0.9073 653 | vn 0.4415 -0.2058 0.8733 654 | vn -0.4415 -0.2058 0.8733 655 | vn 0.4194 -0.3797 0.8245 656 | vn -0.4194 -0.3797 0.8245 657 | vn 0.3106 -0.3403 0.8875 658 | vn -0.3106 -0.3403 0.8875 659 | vn -0.1349 -0.2146 0.9673 660 | vn 0.1349 -0.2146 0.9673 661 | vn -0.3104 -0.1697 0.9353 662 | vn 0.0000 0.0135 0.9999 663 | vn 0.3104 -0.1697 0.9353 664 | vn 0.0284 -0.1986 0.9796 665 | vn -0.0284 -0.1986 0.9796 666 | vn 0.0000 -0.2235 0.9747 667 | vn -0.1624 -0.1997 0.9663 668 | vn 0.1624 -0.1997 0.9663 669 | vn -0.0252 -0.4118 0.9109 670 | vn 0.0000 -0.3312 0.9435 671 | vn 0.0252 -0.4118 0.9109 672 | vn 0.0891 -0.3229 0.9422 673 | vn -0.0891 -0.3229 0.9422 674 | vn 0.1559 -0.1706 0.9729 675 | vn -0.1559 -0.1706 0.9729 676 | vn 0.1386 0.0029 0.9903 677 | vn 0.1802 -0.0578 0.9819 678 | vn -0.1802 -0.0578 0.9819 679 | vn -0.1386 0.0029 0.9903 680 | vn 0.4969 -0.4356 0.7505 681 | vn 0.0000 -0.4576 0.8892 682 | vn 0.0000 -0.0041 1.0000 683 | vn -0.4969 -0.4356 0.7505 684 | vn 0.0000 -0.0342 0.9994 685 | vn 0.0000 -0.4257 0.9048 686 | vn 0.7215 -0.3646 0.5885 687 | vn 0.9246 -0.2129 0.3159 688 | vn 0.5803 -0.7306 0.3597 689 | vn -0.5803 -0.7306 0.3597 690 | vn -0.9246 -0.2129 0.3159 691 | vn -0.7215 -0.3646 0.5885 692 | vn 0.2528 0.3479 0.9028 693 | vn 0.6218 0.7744 0.1168 694 | vn -0.6218 0.7744 0.1168 695 | vn -0.2528 0.3479 0.9028 696 | vn 0.0000 0.5692 0.8221 697 | vn -0.3018 0.9416 0.1492 698 | vn 0.3018 0.9416 0.1492 699 | vn 0.0000 0.7592 0.6508 700 | vn 0.0000 0.7851 0.6193 701 | vn 0.0000 -0.8574 0.5146 702 | vn 0.2206 -0.5640 0.7958 703 | vn 0.0000 -0.5286 0.8489 704 | vn -0.2206 -0.5640 0.7958 705 | vn 0.0000 0.1136 0.9935 706 | vn -0.1992 0.6017 0.7734 707 | vn 0.1992 0.6017 0.7734 708 | vn 0.3664 0.4751 0.8000 709 | vn -0.3664 0.4751 0.8000 710 | vn 0.4296 -0.1849 0.8838 711 | vn -0.4296 -0.1849 0.8838 712 | vn 0.7430 0.0295 0.6686 713 | vn -0.7430 0.0295 0.6686 714 | vn 0.6464 0.1424 0.7496 715 | vn -0.6464 0.1424 0.7496 716 | vn 0.9385 0.3251 0.1160 717 | vn -0.9385 0.3251 0.1160 718 | vn 0.9534 0.2816 0.1079 719 | vn -0.9534 0.2816 0.1079 720 | vn 0.0000 -0.9031 0.4294 721 | vn -0.1140 -0.6151 0.7801 722 | vn 0.1140 -0.6151 0.7801 723 | vn -0.6503 0.0615 0.7572 724 | vn 0.6503 0.0615 0.7572 725 | vn -0.3705 0.5450 0.7521 726 | vn 0.3705 0.5450 0.7521 727 | vn 0.0000 0.6467 0.7627 728 | vn -0.3272 0.4745 0.8171 729 | vn 0.0000 0.5289 0.8487 730 | vn 0.3272 0.4745 0.8171 731 | vn -0.6748 0.1147 0.7290 732 | vn 0.6748 0.1147 0.7290 733 | vn -0.5163 -0.7041 0.4874 734 | vn 0.5163 -0.7041 0.4874 735 | vn 0.0000 -0.6988 0.7153 736 | vn -0.0170 -0.0610 0.9980 737 | vn 0.1649 -0.0897 0.9822 738 | vn 0.0170 -0.0610 0.9980 739 | vn -0.1649 -0.0897 0.9822 740 | vn 0.2358 -0.1089 0.9656 741 | vn -0.2358 -0.1089 0.9656 742 | vn 0.1633 -0.0836 0.9830 743 | vn -0.1633 -0.0836 0.9830 744 | vn 0.0129 -0.1560 0.9876 745 | vn -0.0129 -0.1560 0.9876 746 | vn 0.1998 -0.2072 0.9577 747 | vn -0.1998 -0.2072 0.9577 748 | vn 0.2858 -0.0425 0.9573 749 | vn -0.2858 -0.0425 0.9573 750 | vn 0.2990 -0.0934 0.9497 751 | vn -0.2990 -0.0934 0.9497 752 | vn 0.1870 -0.0655 0.9802 753 | vn -0.1870 -0.0655 0.9802 754 | vn 0.3063 0.0342 0.9513 755 | vn -0.3063 0.0342 0.9513 756 | vn 0.1730 -0.1109 0.9786 757 | vn -0.1730 -0.1109 0.9786 758 | vn 0.1657 0.1129 0.9797 759 | vn -0.1657 0.1129 0.9797 760 | vn 0.1828 0.0367 0.9825 761 | vn -0.1828 0.0367 0.9825 762 | vn 0.5010 -0.3839 0.7756 763 | vn 0.3063 -0.3431 0.8879 764 | vn -0.5010 -0.3839 0.7756 765 | vn -0.3063 -0.3431 0.8879 766 | vn 0.0021 -0.4953 0.8687 767 | vn -0.0021 -0.4953 0.8687 768 | vn -0.1401 -0.7620 0.6322 769 | vn 0.1401 -0.7620 0.6322 770 | vn -0.1943 -0.6160 0.7633 771 | vn 0.1943 -0.6160 0.7633 772 | vn -0.3549 -0.1286 0.9260 773 | vn 0.3549 -0.1286 0.9260 774 | vn -0.2549 0.2241 0.9406 775 | vn 0.2549 0.2241 0.9406 776 | vn -0.0831 0.5416 0.8365 777 | vn 0.0831 0.5416 0.8365 778 | vn 0.1489 0.6135 0.7755 779 | vn -0.1489 0.6135 0.7755 780 | vn 0.4245 0.5609 0.7108 781 | vn -0.4245 0.5609 0.7108 782 | vn 0.6875 0.2974 0.6625 783 | vn -0.6875 0.2974 0.6625 784 | vn 0.7464 -0.2134 0.6303 785 | vn -0.7464 -0.2134 0.6303 786 | vn 0.8052 0.0150 0.5928 787 | vn -0.8052 0.0150 0.5928 788 | vn -0.5046 0.8622 0.0448 789 | vn 0.0000 0.8794 0.4760 790 | vn 0.5046 0.8622 0.0448 791 | vn -0.4770 0.5100 -0.7158 792 | vn 0.4770 0.5100 -0.7158 793 | vn 0.1146 0.6555 -0.7464 794 | vn -0.1146 0.6555 -0.7464 795 | vn 0.3084 0.9138 -0.2642 796 | vn -0.3084 0.9138 -0.2642 797 | vn 0.3515 0.9087 -0.2249 798 | vn -0.3515 0.9087 -0.2249 799 | vn 0.7392 0.6005 -0.3048 800 | vn -0.7392 0.6005 -0.3048 801 | vn 0.9393 -0.3068 -0.1533 802 | vn -0.9393 -0.3068 -0.1533 803 | vn 0.5768 -0.8110 -0.0972 804 | vn -0.5768 -0.8110 -0.0972 805 | vn 0.4394 -0.8925 -0.1016 806 | vn -0.4394 -0.8925 -0.1016 807 | vn 0.0000 -0.3178 -0.9481 808 | vn 0.0000 -0.8051 -0.5931 809 | vn 0.7260 -0.5865 -0.3591 810 | vn 0.3375 -0.2535 -0.9066 811 | vn -0.7260 -0.5865 -0.3591 812 | vn -0.3375 -0.2535 -0.9066 813 | vn 0.0000 -0.2978 -0.9546 814 | vn 0.1293 -0.1789 -0.9753 815 | vn -0.1293 -0.1789 -0.9753 816 | vn 0.0000 -0.8508 -0.5255 817 | vn 0.0993 -0.7679 -0.6327 818 | vn -0.0993 -0.7679 -0.6327 819 | vn 0.5586 -0.4679 -0.6848 820 | vn -0.5586 -0.4679 -0.6848 821 | vn 0.6058 0.0208 -0.7953 822 | vn -0.6058 0.0208 -0.7953 823 | vn 0.7766 -0.0093 -0.6299 824 | vn -0.7766 -0.0093 -0.6299 825 | vn 0.9601 -0.0016 -0.2794 826 | vn -0.9601 -0.0016 -0.2794 827 | vn 0.9731 -0.2302 0.0002 828 | vn 0.9537 -0.1999 0.2246 829 | vn -0.9537 -0.1999 0.2246 830 | vn -0.9731 -0.2302 0.0002 831 | vn 0.8140 -0.5544 0.1732 832 | vn -0.8140 -0.5544 0.1732 833 | vn 0.0000 -0.3004 -0.9538 834 | vn 0.4237 -0.3240 -0.8459 835 | vn 0.5191 -0.6556 -0.5483 836 | vn 0.0000 -0.6966 -0.7174 837 | vn -0.5191 -0.6556 -0.5483 838 | vn -0.4237 -0.3240 -0.8459 839 | vn 0.5213 -0.8255 -0.2162 840 | vn 0.0000 -0.9410 -0.3385 841 | vn -0.5213 -0.8255 -0.2162 842 | vn 0.5887 -0.8081 -0.0185 843 | vn 0.0000 -0.9863 -0.1650 844 | vn -0.5887 -0.8081 -0.0185 845 | vn 0.7152 -0.6950 0.0736 846 | vn 0.9762 -0.2019 0.0787 847 | vn -0.7152 -0.6950 0.0736 848 | vn -0.9762 -0.2019 0.0787 849 | vn 0.0000 0.3141 -0.9494 850 | vn 0.4534 0.1969 -0.8693 851 | vn -0.4534 0.1969 -0.8693 852 | vn 0.0000 0.8267 0.5627 853 | vn 0.4610 0.7338 0.4989 854 | vn 0.4198 0.9069 0.0349 855 | vn 0.0000 0.9997 0.0232 856 | vn -0.4198 0.9069 0.0349 857 | vn -0.4610 0.7338 0.4989 858 | vn 0.4258 0.8032 -0.4165 859 | vn 0.0000 0.8325 -0.5539 860 | vn -0.4258 0.8032 -0.4165 861 | vn 0.7652 0.6244 0.1565 862 | vn 0.4721 0.7778 0.4149 863 | vn -0.7652 0.6244 0.1565 864 | vn -0.4721 0.7778 0.4149 865 | vn 0.7475 0.5326 0.3969 866 | vn 0.6514 0.6814 0.3335 867 | vn -0.7475 0.5326 0.3969 868 | vn -0.6514 0.6814 0.3335 869 | vn 0.8548 0.5181 -0.0301 870 | vn 0.6788 0.7318 -0.0612 871 | vn -0.8548 0.5181 -0.0301 872 | vn -0.6788 0.7318 -0.0612 873 | vn 0.8739 0.3070 -0.3769 874 | vn 0.6440 0.5379 -0.5438 875 | vn -0.8739 0.3070 -0.3769 876 | vn -0.6440 0.5379 -0.5438 877 | vn 0.6260 -0.0259 -0.7794 878 | vn 0.5860 -0.0155 -0.8101 879 | vn -0.5860 -0.0155 -0.8101 880 | vn -0.6260 -0.0259 -0.7794 881 | vn 0.3916 0.8280 0.4012 882 | vn -0.3916 0.8280 0.4012 883 | vn 0.0000 0.6204 0.7843 884 | vn 0.9989 -0.0455 0.0062 885 | vn -0.9989 -0.0455 0.0062 886 | vn 0.8965 0.3044 0.3220 887 | vn -0.8965 0.3044 0.3220 888 | vn 0.5809 -0.8007 -0.1463 889 | vn 0.5730 -0.8037 0.1600 890 | vn -0.5809 -0.8007 -0.1463 891 | vn -0.5730 -0.8037 0.1600 892 | vn 0.2744 -0.9600 -0.0552 893 | vn -0.2744 -0.9600 -0.0552 894 | vn 0.4020 -0.6167 -0.6767 895 | vn 0.5443 -0.4959 -0.6766 896 | vn -0.5443 -0.4959 -0.6766 897 | vn -0.4020 -0.6167 -0.6767 898 | vn 0.0163 0.8736 0.4863 899 | vn -0.2878 0.7388 0.6094 900 | vn 0.4590 -0.0631 0.8862 901 | vn 0.5420 -0.0674 0.8376 902 | vn -0.4590 -0.0631 0.8862 903 | vn 0.2878 0.7388 0.6094 904 | vn -0.0163 0.8736 0.4863 905 | vn -0.5420 -0.0674 0.8376 906 | vn 0.3174 -0.0930 0.9437 907 | vn 0.3604 0.8605 0.3600 908 | vn -0.3174 -0.0930 0.9437 909 | vn -0.3604 0.8605 0.3600 910 | vn -0.1201 -0.0897 0.9887 911 | vn 0.7896 0.1790 0.5869 912 | vn 0.1201 -0.0897 0.9887 913 | vn -0.7896 0.1790 0.5869 914 | vn -0.0240 0.2739 0.9614 915 | vn 0.6731 -0.4998 0.5450 916 | vn 0.0240 0.2739 0.9614 917 | vn -0.6731 -0.4998 0.5450 918 | vn 0.4922 0.2738 0.8263 919 | vn 0.4719 -0.7796 0.4117 920 | vn -0.4922 0.2738 0.8263 921 | vn -0.4719 -0.7796 0.4116 922 | vn 0.3413 0.3527 0.8712 923 | vn -0.0439 -0.6481 0.7602 924 | vn -0.3413 0.3527 0.8712 925 | vn 0.0439 -0.6481 0.7602 926 | vn -0.1665 0.9539 0.2497 927 | vn 0.2330 0.8788 0.4164 928 | vn -0.2330 0.8788 0.4164 929 | vn 0.1665 0.9539 0.2497 930 | vn -0.7613 0.6471 0.0399 931 | vn 0.7613 0.6471 0.0399 932 | vn -0.9810 -0.0934 0.1698 933 | vn 0.9810 -0.0934 0.1698 934 | vn -0.1410 -0.7728 0.6188 935 | vn 0.1410 -0.7728 0.6188 936 | vn 0.5587 -0.6583 0.5044 937 | vn -0.5587 -0.6583 0.5044 938 | vn 0.6878 -0.5533 0.4698 939 | vn -0.6878 -0.5533 0.4698 940 | vn 0.7450 0.0855 0.6615 941 | vn 0.8615 -0.4880 -0.1400 942 | vn -0.7450 0.0855 0.6615 943 | vn -0.8615 -0.4880 -0.1400 944 | vn 0.7427 -0.2611 0.6166 945 | vn -0.7427 -0.2611 0.6166 946 | vn 0.5933 0.5663 0.5720 947 | vn -0.5933 0.5663 0.5720 948 | vn 0.8837 -0.0624 0.4639 949 | vn 0.9210 -0.1749 0.3480 950 | vn -0.9210 -0.1749 0.3480 951 | vn -0.8837 -0.0624 0.4639 952 | vn 0.8589 0.0371 0.5108 953 | vn 0.5731 0.7262 0.3795 954 | vn -0.8589 0.0371 0.5108 955 | vn -0.5731 0.7262 0.3795 956 | vn 0.7481 -0.5799 0.3224 957 | vn 0.8720 -0.4240 0.2446 958 | vn -0.8720 -0.4240 0.2446 959 | vn -0.7481 -0.5799 0.3224 960 | vn 0.6963 -0.5412 0.4714 961 | vn -0.6963 -0.5412 0.4714 962 | vn 0.6669 -0.4348 0.6052 963 | vn 0.6358 -0.4092 0.6544 964 | vn -0.6669 -0.4348 0.6052 965 | vn -0.6358 -0.4092 0.6544 966 | vn 0.5714 -0.4259 0.7015 967 | vn -0.5714 -0.4259 0.7015 968 | vn 0.7837 0.2514 0.5680 969 | vn -0.7837 0.2514 0.5680 970 | vn 0.4447 0.3740 0.8138 971 | vn -0.4447 0.3740 0.8138 972 | vn 0.3739 0.3687 0.8510 973 | vn -0.3739 0.3687 0.8510 974 | vn 0.6600 0.3495 0.6650 975 | vn -0.6600 0.3495 0.6650 976 | vn -0.0507 0.9518 0.3023 977 | vn 0.0507 0.9518 0.3023 978 | vn 0.4844 -0.3373 0.8072 979 | vn -0.4844 -0.3373 0.8072 980 | vn -0.2485 -0.5826 0.7738 981 | vn 0.2485 -0.5826 0.7738 982 | vn -0.7433 -0.0973 0.6618 983 | vn 0.7433 -0.0973 0.6618 984 | vn -0.5392 0.4506 0.7114 985 | vn 0.5392 0.4506 0.7114 986 | vn 0.0873 0.7400 0.6668 987 | vn -0.0873 0.7400 0.6668 988 | vn 0.3854 0.1162 0.9153 989 | vn 0.1983 0.0051 0.9801 990 | vn -0.3854 0.1162 0.9153 991 | vn -0.1983 0.0051 0.9801 992 | vn 0.4315 -0.0331 0.9015 993 | vn 0.3281 0.0002 0.9446 994 | vn -0.4315 -0.0331 0.9015 995 | vn -0.3281 0.0002 0.9446 996 | vn 0.3447 -0.0767 0.9355 997 | vn 0.3178 0.0937 0.9435 998 | vn -0.3447 -0.0767 0.9355 999 | vn -0.3178 0.0937 0.9435 1000 | vn 0.4365 -0.0136 0.8996 1001 | vn 0.3573 0.2980 0.8851 1002 | vn -0.4365 -0.0136 0.8996 1003 | vn -0.3573 0.2980 0.8851 1004 | vn -0.0797 -0.8453 -0.5283 1005 | vn -0.0418 -0.6989 -0.7140 1006 | vn 0.0797 -0.8453 -0.5283 1007 | vn 0.0418 -0.6989 -0.7140 1008 | vn 0.6149 -0.4906 -0.6174 1009 | vn -0.6149 -0.4906 -0.6174 1010 | vn 0.9234 0.0856 -0.3741 1011 | vn -0.9234 0.0856 -0.3741 1012 | vn 0.3048 0.6219 -0.7213 1013 | vn -0.3048 0.6219 -0.7213 1014 | vn -0.4176 0.5586 -0.7166 1015 | vn 0.4176 0.5586 -0.7166 1016 | vn -0.6562 0.5715 -0.4927 1017 | vn 0.6562 0.5715 -0.4927 1018 | s 1 1019 | f 47//1 1//2 3//3 45//4 1020 | f 4//5 2//6 48//7 46//8 1021 | f 45//4 3//3 5//9 43//10 1022 | f 6//11 4//5 46//8 44//12 1023 | f 3//3 9//13 7//14 5//9 1024 | f 8//15 10//16 4//5 6//11 1025 | f 1//2 11//17 9//13 3//3 1026 | f 10//16 12//18 2//6 4//5 1027 | f 11//17 13//19 15//20 9//13 1028 | f 16//21 14//22 12//18 10//16 1029 | f 9//13 15//20 17//23 7//14 1030 | f 18//24 16//21 10//16 8//15 1031 | f 15//20 21//25 19//26 17//23 1032 | f 20//27 22//28 16//21 18//24 1033 | f 13//19 23//29 21//25 15//20 1034 | f 22//28 24//30 14//22 16//21 1035 | f 23//29 25//31 27//32 21//25 1036 | f 28//33 26//34 24//30 22//28 1037 | f 21//25 27//32 29//35 19//26 1038 | f 30//36 28//33 22//28 20//27 1039 | f 27//32 33//37 31//38 29//35 1040 | f 32//39 34//40 28//33 30//36 1041 | f 25//31 35//41 33//37 27//32 1042 | f 34//40 36//42 26//34 28//33 1043 | f 35//41 37//43 39//44 33//37 1044 | f 40//45 38//46 36//42 34//40 1045 | f 33//37 39//44 41//47 31//38 1046 | f 42//48 40//45 34//40 32//39 1047 | f 39//44 45//4 43//10 41//47 1048 | f 44//12 46//8 40//45 42//48 1049 | f 37//43 47//1 45//4 39//44 1050 | f 46//8 48//7 38//46 40//45 1051 | f 47//1 37//43 51//49 49//50 1052 | f 52//51 38//46 48//7 50//52 1053 | f 37//43 35//41 53//53 51//49 1054 | f 54//54 36//42 38//46 52//51 1055 | f 35//41 25//31 55//55 53//53 1056 | f 56//56 26//34 36//42 54//54 1057 | f 25//31 23//29 57//57 55//55 1058 | f 58//58 24//30 26//34 56//56 1059 | f 23//29 13//19 59//59 57//57 1060 | f 60//60 14//22 24//30 58//58 1061 | f 13//19 11//17 63//61 59//59 1062 | f 64//62 12//18 14//22 60//60 1063 | f 11//17 1//2 65//63 63//61 1064 | f 66//64 2//6 12//18 64//62 1065 | f 1//2 47//1 49//50 65//63 1066 | f 50//52 48//7 2//6 66//64 1067 | f 61//65 65//63 49//50 1068 | f 50//52 66//64 62//66 1069 | f 63//61 65//63 61//65 1070 | f 62//66 66//64 64//62 1071 | f 61//65 59//59 63//61 1072 | f 64//62 60//60 62//66 1073 | f 61//65 57//57 59//59 1074 | f 60//60 58//58 62//66 1075 | f 61//65 55//55 57//57 1076 | f 58//58 56//56 62//66 1077 | f 61//65 53//53 55//55 1078 | f 56//56 54//54 62//66 1079 | f 61//65 51//49 53//53 1080 | f 54//54 52//51 62//66 1081 | f 61//65 49//50 51//49 1082 | f 52//51 50//52 62//66 1083 | f 89//67 174//68 176//69 91//70 1084 | f 176//69 175//71 90//72 91//70 1085 | f 87//73 172//74 174//68 89//67 1086 | f 175//71 173//75 88//76 90//72 1087 | f 85//77 170//78 172//74 87//73 1088 | f 173//75 171//79 86//80 88//76 1089 | f 83//81 168//82 170//78 85//77 1090 | f 171//79 169//83 84//84 86//80 1091 | f 81//85 166//86 168//82 83//81 1092 | f 169//83 167//87 82//88 84//84 1093 | f 79//89 92//90 146//91 164//92 1094 | f 147//93 93//94 80//95 165//96 1095 | f 92//90 94//97 148//98 146//91 1096 | f 149//99 95//100 93//94 147//93 1097 | f 94//97 96//101 150//102 148//98 1098 | f 151//103 97//104 95//100 149//99 1099 | f 96//101 98//105 152//106 150//102 1100 | f 153//107 99//108 97//104 151//103 1101 | f 98//105 100//109 154//110 152//106 1102 | f 155//111 101//112 99//108 153//107 1103 | f 100//109 102//113 156//114 154//110 1104 | f 157//115 103//116 101//112 155//111 1105 | f 102//113 104//117 158//118 156//114 1106 | f 159//119 105//120 103//116 157//115 1107 | f 104//117 106//121 160//122 158//118 1108 | f 161//123 107//124 105//120 159//119 1109 | f 106//121 108//125 162//126 160//122 1110 | f 163//127 109//128 107//124 161//123 1111 | f 108//125 67//129 68//130 162//126 1112 | f 68//130 67//129 109//128 163//127 1113 | f 110//131 128//132 160//122 162//126 1114 | f 161//123 129//133 111//134 163//127 1115 | f 128//132 179//135 158//118 160//122 1116 | f 159//119 180//136 129//133 161//123 1117 | f 126//137 156//114 158//118 179//135 1118 | f 159//119 157//115 127//138 180//136 1119 | f 124//139 154//110 156//114 126//137 1120 | f 157//115 155//111 125//140 127//138 1121 | f 122//141 152//106 154//110 124//139 1122 | f 155//111 153//107 123//142 125//140 1123 | f 120//143 150//102 152//106 122//141 1124 | f 153//107 151//103 121//144 123//142 1125 | f 118//145 148//98 150//102 120//143 1126 | f 151//103 149//99 119//146 121//144 1127 | f 116//147 146//91 148//98 118//145 1128 | f 149//99 147//93 117//148 119//146 1129 | f 114//149 164//92 146//91 116//147 1130 | f 147//93 165//96 115//150 117//148 1131 | f 114//149 181//151 177//152 164//92 1132 | f 177//152 182//153 115//150 165//96 1133 | f 110//131 162//126 68//130 112//154 1134 | f 68//130 163//127 111//134 113//155 1135 | f 112//154 68//130 178//156 183//157 1136 | f 178//156 68//130 113//155 184//158 1137 | f 177//152 181//151 183//157 178//156 1138 | f 184//158 182//153 177//152 178//156 1139 | f 135//159 137//160 176//69 174//68 1140 | f 176//69 137//160 136//161 175//71 1141 | f 133//162 135//159 174//68 172//74 1142 | f 175//71 136//161 134//163 173//75 1143 | f 131//164 133//162 172//74 170//78 1144 | f 173//75 134//163 132//165 171//79 1145 | f 166//86 187//166 185//167 168//82 1146 | f 186//168 188//169 167//87 169//83 1147 | f 131//164 170//78 168//82 185//167 1148 | f 169//83 171//79 132//165 186//168 1149 | f 144//170 190//171 189//172 187//166 1150 | f 189//172 190//171 145//173 188//169 1151 | f 185//167 187//166 189//172 69//174 1152 | f 189//172 188//169 186//168 69//174 1153 | f 130//175 131//164 185//167 69//174 1154 | f 186//168 132//165 130//175 69//174 1155 | f 142//176 193//177 191//178 144//170 1156 | f 192//179 194//180 143//181 145//173 1157 | f 140//182 195//183 193//177 142//176 1158 | f 194//180 196//184 141//185 143//181 1159 | f 139//186 197//187 195//183 140//182 1160 | f 196//184 198//188 139//186 141//185 1161 | f 138//189 71//190 197//187 139//186 1162 | f 198//188 71//190 138//189 139//186 1163 | f 190//171 144//170 191//178 70//191 1164 | f 192//179 145//173 190//171 70//191 1165 | f 70//191 191//178 206//192 208//193 1166 | f 207//194 192//179 70//191 208//193 1167 | f 71//190 199//195 200//196 197//187 1168 | f 201//197 199//195 71//190 198//188 1169 | f 197//187 200//196 202//198 195//183 1170 | f 203//199 201//197 198//188 196//184 1171 | f 195//183 202//198 204//200 193//177 1172 | f 205//201 203//199 196//184 194//180 1173 | f 193//177 204//200 206//192 191//178 1174 | f 207//194 205//201 194//180 192//179 1175 | f 199//195 204//200 202//198 200//196 1176 | f 203//199 205//201 199//195 201//197 1177 | f 199//195 208//193 206//192 204//200 1178 | f 207//194 208//193 199//195 205//201 1179 | f 139//186 140//182 164//92 177//152 1180 | f 165//96 141//185 139//186 177//152 1181 | f 140//182 142//176 211//202 164//92 1182 | f 212//203 143//181 141//185 165//96 1183 | f 142//176 144//170 213//204 211//202 1184 | f 214//205 145//173 143//181 212//203 1185 | f 144//170 187//166 166//86 213//204 1186 | f 167//87 188//169 145//173 214//205 1187 | f 81//85 209//206 213//204 166//86 1188 | f 214//205 210//207 82//88 167//87 1189 | f 209//206 215//208 211//202 213//204 1190 | f 212//203 216//209 210//207 214//205 1191 | f 79//89 164//92 211//202 215//208 1192 | f 212//203 165//96 80//95 216//209 1193 | f 131//164 130//175 72//210 222//211 1194 | f 72//210 130//175 132//165 223//212 1195 | f 133//162 131//164 222//211 220//213 1196 | f 223//212 132//165 134//163 221//214 1197 | f 135//159 133//162 220//213 218//215 1198 | f 221//214 134//163 136//161 219//216 1199 | f 137//160 135//159 218//215 217//217 1200 | f 219//216 136//161 137//160 217//217 1201 | f 217//217 218//215 229//218 231//219 1202 | f 230//220 219//216 217//217 231//219 1203 | f 218//215 220//213 227//221 229//218 1204 | f 228//222 221//214 219//216 230//220 1205 | f 220//213 222//211 225//223 227//221 1206 | f 226//224 223//212 221//214 228//222 1207 | f 222//211 72//210 224//225 225//223 1208 | f 224//225 72//210 223//212 226//224 1209 | f 224//225 231//219 229//218 225//223 1210 | f 230//220 231//219 224//225 226//224 1211 | f 225//223 229//218 227//221 1212 | f 228//222 230//220 226//224 1213 | f 183//157 181//151 234//226 232//227 1214 | f 235//228 182//153 184//158 233//229 1215 | f 112//154 183//157 232//227 254//230 1216 | f 233//229 184//158 113//155 255//231 1217 | f 110//131 112//154 254//230 256//232 1218 | f 255//231 113//155 111//134 257//233 1219 | f 181//151 114//149 252//234 234//226 1220 | f 253//235 115//150 182//153 235//228 1221 | f 114//149 116//147 250//236 252//234 1222 | f 251//237 117//148 115//150 253//235 1223 | f 116//147 118//145 248//238 250//236 1224 | f 249//239 119//146 117//148 251//237 1225 | f 118//145 120//143 246//240 248//238 1226 | f 247//241 121//144 119//146 249//239 1227 | f 120//143 122//141 244//242 246//240 1228 | f 245//243 123//142 121//144 247//241 1229 | f 122//141 124//139 242//244 244//242 1230 | f 243//245 125//140 123//142 245//243 1231 | f 124//139 126//137 240//246 242//244 1232 | f 241//247 127//138 125//140 243//245 1233 | f 126//137 179//135 236//248 240//246 1234 | f 237//249 180//136 127//138 241//247 1235 | f 179//135 128//132 238//250 236//248 1236 | f 239//251 129//133 180//136 237//249 1237 | f 128//132 110//131 256//232 238//250 1238 | f 257//233 111//134 129//133 239//251 1239 | f 238//250 256//232 258//252 276//253 1240 | f 259//254 257//233 239//251 277//255 1241 | f 236//248 238//250 276//253 278//256 1242 | f 277//255 239//251 237//249 279//257 1243 | f 240//246 236//248 278//256 274//258 1244 | f 279//257 237//249 241//247 275//259 1245 | f 242//244 240//246 274//258 272//260 1246 | f 275//259 241//247 243//245 273//261 1247 | f 244//242 242//244 272//260 270//262 1248 | f 273//261 243//245 245//243 271//263 1249 | f 246//240 244//242 270//262 268//264 1250 | f 271//263 245//243 247//241 269//265 1251 | f 248//238 246//240 268//264 266//266 1252 | f 269//265 247//241 249//239 267//267 1253 | f 250//236 248//238 266//266 264//268 1254 | f 267//267 249//239 251//237 265//269 1255 | f 252//234 250//236 264//268 262//270 1256 | f 265//269 251//237 253//235 263//271 1257 | f 234//226 252//234 262//270 280//272 1258 | f 263//271 253//235 235//228 281//273 1259 | f 256//232 254//230 260//274 258//252 1260 | f 261//275 255//231 257//233 259//254 1261 | f 254//230 232//227 282//276 260//274 1262 | f 283//277 233//229 255//231 261//275 1263 | f 232//227 234//226 280//272 282//276 1264 | f 281//273 235//228 233//229 283//277 1265 | f 67//129 108//125 284//278 73//279 1266 | f 285//280 109//128 67//129 73//279 1267 | f 108//125 106//121 286//281 284//278 1268 | f 287//282 107//124 109//128 285//280 1269 | f 106//121 104//117 288//283 286//281 1270 | f 289//284 105//120 107//124 287//282 1271 | f 104//117 102//113 290//285 288//283 1272 | f 291//286 103//116 105//120 289//284 1273 | f 102//113 100//109 292//287 290//285 1274 | f 293//288 101//112 103//116 291//286 1275 | f 100//109 98//105 294//289 292//287 1276 | f 295//290 99//108 101//112 293//288 1277 | f 98//105 96//101 296//291 294//289 1278 | f 297//292 97//104 99//108 295//290 1279 | f 96//101 94//97 298//293 296//291 1280 | f 299//294 95//100 97//104 297//292 1281 | f 94//97 92//90 300//295 298//293 1282 | f 301//296 93//94 95//100 299//294 1283 | f 308//297 309//298 328//299 338//300 1284 | f 329//301 309//298 308//297 339//302 1285 | f 307//303 308//297 338//300 336//304 1286 | f 339//302 308//297 307//303 337//305 1287 | f 306//306 307//303 336//304 340//307 1288 | f 337//305 307//303 306//306 341//308 1289 | f 89//67 91//70 306//306 340//307 1290 | f 306//306 91//70 90//72 341//308 1291 | f 87//73 89//67 340//307 334//309 1292 | f 341//308 90//72 88//76 335//310 1293 | f 85//77 87//73 334//309 330//311 1294 | f 335//310 88//76 86//80 331//312 1295 | f 83//81 85//77 330//311 332//313 1296 | f 331//312 86//80 84//84 333//314 1297 | f 330//311 336//304 338//300 332//313 1298 | f 339//302 337//305 331//312 333//314 1299 | f 330//311 334//309 340//307 336//304 1300 | f 341//308 335//310 331//312 337//305 1301 | f 326//315 332//313 338//300 328//299 1302 | f 339//302 333//314 327//316 329//301 1303 | f 81//85 83//81 332//313 326//315 1304 | f 333//314 84//84 82//88 327//316 1305 | f 209//206 342//317 344//318 215//208 1306 | f 345//319 343//320 210//207 216//209 1307 | f 81//85 326//315 342//317 209//206 1308 | f 343//320 327//316 82//88 210//207 1309 | f 79//89 215//208 344//318 346//321 1310 | f 345//319 216//209 80//95 347//322 1311 | f 79//89 346//321 300//295 92//90 1312 | f 301//296 347//322 80//95 93//94 1313 | f 77//323 324//324 352//325 304//326 1314 | f 353//327 325//328 77//323 304//326 1315 | f 304//326 352//325 350//329 78//330 1316 | f 351//331 353//327 304//326 78//330 1317 | f 78//330 350//329 348//332 305//333 1318 | f 349//334 351//331 78//330 305//333 1319 | f 305//333 348//332 328//299 309//298 1320 | f 329//301 349//334 305//333 309//298 1321 | f 326//315 328//299 348//332 342//317 1322 | f 349//334 329//301 327//316 343//320 1323 | f 296//291 298//293 318//335 310//336 1324 | f 319//337 299//294 297//292 311//338 1325 | f 76//339 316//340 324//324 77//323 1326 | f 325//328 317//341 76//339 77//323 1327 | f 302//342 358//343 356//344 303//345 1328 | f 357//346 359//347 302//342 303//345 1329 | f 303//345 356//344 354//348 75//349 1330 | f 355//350 357//346 303//345 75//349 1331 | f 75//349 354//348 316//340 76//339 1332 | f 317//341 355//350 75//349 76//339 1333 | f 292//287 294//289 362//351 364//352 1334 | f 363//353 295//290 293//288 365//354 1335 | f 364//352 362//351 368//355 366//356 1336 | f 369//357 363//353 365//354 367//358 1337 | f 366//356 368//355 370//359 372//360 1338 | f 371//361 369//357 367//358 373//362 1339 | f 372//360 370//359 376//363 374//364 1340 | f 377//365 371//361 373//362 375//366 1341 | f 314//367 378//368 374//364 376//363 1342 | f 375//366 379//369 315//370 377//365 1343 | f 316//340 354//348 374//364 378//368 1344 | f 375//366 355//350 317//341 379//369 1345 | f 354//348 356//344 372//360 374//364 1346 | f 373//362 357//346 355//350 375//366 1347 | f 356//344 358//343 366//356 372//360 1348 | f 367//358 359//347 357//346 373//362 1349 | f 358//343 360//371 364//352 366//356 1350 | f 365//354 361//372 359//347 367//358 1351 | f 290//285 292//287 364//352 360//371 1352 | f 365//354 293//288 291//286 361//372 1353 | f 74//373 360//371 358//343 302//342 1354 | f 359//347 361//372 74//373 302//342 1355 | f 284//278 286//281 288//283 290//285 1356 | f 289//284 287//282 285//280 291//286 1357 | f 284//278 290//285 360//371 74//373 1358 | f 361//372 291//286 285//280 74//373 1359 | f 73//279 284//278 74//373 1360 | f 74//373 285//280 73//279 1361 | f 294//289 296//291 310//336 362//351 1362 | f 311//338 297//292 295//290 363//353 1363 | f 310//336 312//374 368//355 362//351 1364 | f 369//357 313//375 311//338 363//353 1365 | f 312//374 382//376 370//359 368//355 1366 | f 371//361 383//377 313//375 369//357 1367 | f 314//367 376//363 370//359 382//376 1368 | f 371//361 377//365 315//370 383//377 1369 | f 348//332 350//329 386//378 384//379 1370 | f 387//380 351//331 349//334 385//381 1371 | f 318//335 384//379 386//378 320//382 1372 | f 387//380 385//381 319//337 321//383 1373 | f 298//293 300//295 384//379 318//335 1374 | f 385//381 301//296 299//294 319//337 1375 | f 300//295 344//318 342//317 384//379 1376 | f 343//320 345//319 301//296 385//381 1377 | f 342//317 348//332 384//379 1378 | f 385//381 349//334 343//320 1379 | f 300//295 346//321 344//318 1380 | f 345//319 347//322 301//296 1381 | f 314//367 322//384 380//385 378//368 1382 | f 381//386 323//387 315//370 379//369 1383 | f 316//340 378//368 380//385 324//324 1384 | f 381//386 379//369 317//341 325//328 1385 | f 320//382 386//378 380//385 322//384 1386 | f 381//386 387//380 321//383 323//387 1387 | f 350//329 352//325 380//385 386//378 1388 | f 381//386 353//327 351//331 387//380 1389 | f 324//324 380//385 352//325 1390 | f 353//327 381//386 325//328 1391 | f 400//388 388//389 414//390 402//391 1392 | f 415//392 389//393 401//394 403//395 1393 | f 400//388 402//391 404//396 398//397 1394 | f 405//398 403//395 401//394 399//399 1395 | f 398//397 404//396 406//400 396//401 1396 | f 407//402 405//398 399//399 397//403 1397 | f 396//401 406//400 408//404 394//405 1398 | f 409//406 407//402 397//403 395//407 1399 | f 394//405 408//404 410//408 392//409 1400 | f 411//410 409//406 395//407 393//411 1401 | f 392//409 410//408 412//412 390//413 1402 | f 413//414 411//410 393//411 391//415 1403 | f 410//408 420//416 418//417 412//412 1404 | f 419//418 421//419 411//410 413//414 1405 | f 408//404 422//420 420//416 410//408 1406 | f 421//419 423//421 409//406 411//410 1407 | f 406//400 424//422 422//420 408//404 1408 | f 423//421 425//423 407//402 409//406 1409 | f 404//396 426//424 424//422 406//400 1410 | f 425//423 427//425 405//398 407//402 1411 | f 402//391 428//426 426//424 404//396 1412 | f 427//425 429//427 403//395 405//398 1413 | f 402//391 414//390 416//428 428//426 1414 | f 417//429 415//392 403//395 429//427 1415 | f 318//335 320//382 444//430 442//431 1416 | f 445//432 321//383 319//337 443//433 1417 | f 320//382 390//413 412//412 444//430 1418 | f 413//414 391//415 321//383 445//432 1419 | f 310//336 318//335 442//431 312//374 1420 | f 443//433 319//337 311//338 313//375 1421 | f 382//376 430//434 414//390 388//389 1422 | f 415//392 431//435 383//377 389//393 1423 | f 412//412 418//417 440//436 444//430 1424 | f 441//437 419//418 413//414 445//432 1425 | f 438//438 446//439 444//430 440//436 1426 | f 445//432 447//440 439//441 441//437 1427 | f 434//442 446//439 438//438 436//443 1428 | f 439//441 447//440 435//444 437//445 1429 | f 432//446 448//447 446//439 434//442 1430 | f 447//440 449//448 433//449 435//444 1431 | f 430//434 448//447 432//446 450//450 1432 | f 433//449 449//448 431//435 451//451 1433 | f 414//390 430//434 450//450 416//428 1434 | f 451//451 431//435 415//392 417//429 1435 | f 312//374 448//447 430//434 382//376 1436 | f 431//435 449//448 313//375 383//377 1437 | f 312//374 442//431 446//439 448//447 1438 | f 447//440 443//433 313//375 449//448 1439 | f 442//431 444//430 446//439 1440 | f 447//440 445//432 443//433 1441 | f 416//428 450//450 452//452 476//453 1442 | f 453//454 451//451 417//429 477//455 1443 | f 450//450 432//446 462//456 452//452 1444 | f 463//457 433//449 451//451 453//454 1445 | f 432//446 434//442 460//458 462//456 1446 | f 461//459 435//444 433//449 463//457 1447 | f 434//442 436//443 458//460 460//458 1448 | f 459//461 437//445 435//444 461//459 1449 | f 436//443 438//438 456//462 458//460 1450 | f 457//463 439//441 437//445 459//461 1451 | f 438//438 440//436 454//464 456//462 1452 | f 455//465 441//437 439//441 457//463 1453 | f 440//436 418//417 474//466 454//464 1454 | f 475//467 419//418 441//437 455//465 1455 | f 428//426 416//428 476//453 464//468 1456 | f 477//455 417//429 429//427 465//469 1457 | f 426//424 428//426 464//468 466//470 1458 | f 465//469 429//427 427//425 467//471 1459 | f 424//422 426//424 466//470 468//472 1460 | f 467//471 427//425 425//423 469//473 1461 | f 422//420 424//422 468//472 470//474 1462 | f 469//473 425//423 423//421 471//475 1463 | f 420//416 422//420 470//474 472//476 1464 | f 471//475 423//421 421//419 473//477 1465 | f 418//417 420//416 472//476 474//466 1466 | f 473//477 421//419 419//418 475//467 1467 | f 458//460 456//462 480//478 478//479 1468 | f 481//480 457//463 459//461 479//481 1469 | f 478//479 480//478 482//482 484//483 1470 | f 483//484 481//480 479//481 485//485 1471 | f 484//483 482//482 488//486 486//487 1472 | f 489//488 483//484 485//485 487//489 1473 | f 486//487 488//486 490//490 492//491 1474 | f 491//492 489//488 487//489 493//493 1475 | f 464//468 476//453 486//487 492//491 1476 | f 487//489 477//455 465//469 493//493 1477 | f 452//452 484//483 486//487 476//453 1478 | f 487//489 485//485 453//454 477//455 1479 | f 452//452 462//456 478//479 484//483 1480 | f 479//481 463//457 453//454 485//485 1481 | f 458//460 478//479 462//456 460//458 1482 | f 463//457 479//481 459//461 461//459 1483 | f 454//464 474//466 480//478 456//462 1484 | f 481//480 475//467 455//465 457//463 1485 | f 472//476 482//482 480//478 474//466 1486 | f 481//480 483//484 473//477 475//467 1487 | f 470//474 488//486 482//482 472//476 1488 | f 483//484 489//488 471//475 473//477 1489 | f 468//472 490//490 488//486 470//474 1490 | f 489//488 491//492 469//473 471//475 1491 | f 466//470 492//491 490//490 468//472 1492 | f 491//492 493//493 467//471 469//473 1493 | f 464//468 492//491 466//470 1494 | f 467//471 493//493 465//469 1495 | f 392//409 390//413 504//494 502//495 1496 | f 505//496 391//415 393//411 503//497 1497 | f 394//405 392//409 502//495 500//498 1498 | f 503//497 393//411 395//407 501//499 1499 | f 396//401 394//405 500//498 498//500 1500 | f 501//499 395//407 397//403 499//501 1501 | f 398//397 396//401 498//500 496//502 1502 | f 499//501 397//403 399//399 497//503 1503 | f 400//388 398//397 496//502 494//504 1504 | f 497//503 399//399 401//394 495//505 1505 | f 388//389 400//388 494//504 506//506 1506 | f 495//505 401//394 389//393 507//507 1507 | f 494//504 502//495 504//494 506//506 1508 | f 505//496 503//497 495//505 507//507 1509 | f 494//504 496//502 500//498 502//495 1510 | f 501//499 497//503 495//505 503//497 1511 | f 496//502 498//500 500//498 1512 | f 501//499 499//501 497//503 1513 | f 314//367 382//376 388//389 506//506 1514 | f 389//393 383//377 315//370 507//507 1515 | f 314//367 506//506 504//494 322//384 1516 | f 505//496 507//507 315//370 323//387 1517 | f 320//382 322//384 504//494 390//413 1518 | f 505//496 323//387 321//383 391//415 1519 | -------------------------------------------------------------------------------- /examples/textures/chavant.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/declension/elm-obj-loader/d3cc9c5b9e01269775550d03b689fe3065020746/examples/textures/chavant.jpg -------------------------------------------------------------------------------- /examples/textures/elmLogoDiffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/declension/elm-obj-loader/d3cc9c5b9e01269775550d03b689fe3065020746/examples/textures/elmLogoDiffuse.png -------------------------------------------------------------------------------- /examples/textures/elmLogoNorm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/declension/elm-obj-loader/d3cc9c5b9e01269775550d03b689fe3065020746/examples/textures/elmLogoNorm.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elm-obj-loader", 3 | "version": "1.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ajv": { 8 | "version": "6.12.2", 9 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", 10 | "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", 11 | "dev": true, 12 | "requires": { 13 | "fast-deep-equal": "^3.1.1", 14 | "fast-json-stable-stringify": "^2.0.0", 15 | "json-schema-traverse": "^0.4.1", 16 | "uri-js": "^4.2.2" 17 | } 18 | }, 19 | "ansi-styles": { 20 | "version": "3.2.1", 21 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 22 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 23 | "dev": true, 24 | "requires": { 25 | "color-convert": "^1.9.0" 26 | } 27 | }, 28 | "anymatch": { 29 | "version": "3.1.1", 30 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 31 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 32 | "dev": true, 33 | "requires": { 34 | "normalize-path": "^3.0.0", 35 | "picomatch": "^2.0.4" 36 | } 37 | }, 38 | "asn1": { 39 | "version": "0.2.4", 40 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 41 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 42 | "dev": true, 43 | "requires": { 44 | "safer-buffer": "~2.1.0" 45 | } 46 | }, 47 | "assert-plus": { 48 | "version": "1.0.0", 49 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 50 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", 51 | "dev": true 52 | }, 53 | "asynckit": { 54 | "version": "0.4.0", 55 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 56 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", 57 | "dev": true 58 | }, 59 | "aws-sign2": { 60 | "version": "0.7.0", 61 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 62 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", 63 | "dev": true 64 | }, 65 | "aws4": { 66 | "version": "1.10.0", 67 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", 68 | "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", 69 | "dev": true 70 | }, 71 | "balanced-match": { 72 | "version": "1.0.0", 73 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 74 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 75 | "dev": true 76 | }, 77 | "bcrypt-pbkdf": { 78 | "version": "1.0.2", 79 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 80 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 81 | "dev": true, 82 | "requires": { 83 | "tweetnacl": "^0.14.3" 84 | } 85 | }, 86 | "binary": { 87 | "version": "0.3.0", 88 | "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", 89 | "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", 90 | "dev": true, 91 | "requires": { 92 | "buffers": "~0.1.1", 93 | "chainsaw": "~0.1.0" 94 | } 95 | }, 96 | "binary-extensions": { 97 | "version": "2.0.0", 98 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", 99 | "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", 100 | "dev": true 101 | }, 102 | "binwrap": { 103 | "version": "0.2.2", 104 | "resolved": "https://registry.npmjs.org/binwrap/-/binwrap-0.2.2.tgz", 105 | "integrity": "sha512-Y+Wvypk3JhH5GPZAvlwJAWOVH/OsOhQMSj37vySuWHwQivoALplPxfBA8b973rFJI7OS+O+1YmmYXIiEXVMAcw==", 106 | "dev": true, 107 | "requires": { 108 | "mustache": "^3.0.1", 109 | "request": "^2.88.0", 110 | "request-promise": "^4.2.4", 111 | "tar": "^4.4.10", 112 | "unzip-stream": "^0.3.0" 113 | } 114 | }, 115 | "bluebird": { 116 | "version": "3.7.2", 117 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", 118 | "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", 119 | "dev": true 120 | }, 121 | "brace-expansion": { 122 | "version": "1.1.11", 123 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 124 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 125 | "dev": true, 126 | "requires": { 127 | "balanced-match": "^1.0.0", 128 | "concat-map": "0.0.1" 129 | } 130 | }, 131 | "braces": { 132 | "version": "3.0.2", 133 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 134 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 135 | "dev": true, 136 | "requires": { 137 | "fill-range": "^7.0.1" 138 | } 139 | }, 140 | "buffers": { 141 | "version": "0.1.1", 142 | "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", 143 | "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", 144 | "dev": true 145 | }, 146 | "caseless": { 147 | "version": "0.12.0", 148 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 149 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", 150 | "dev": true 151 | }, 152 | "chainsaw": { 153 | "version": "0.1.0", 154 | "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", 155 | "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", 156 | "dev": true, 157 | "requires": { 158 | "traverse": ">=0.3.0 <0.4" 159 | } 160 | }, 161 | "chalk": { 162 | "version": "2.4.2", 163 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 164 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 165 | "dev": true, 166 | "requires": { 167 | "ansi-styles": "^3.2.1", 168 | "escape-string-regexp": "^1.0.5", 169 | "supports-color": "^5.3.0" 170 | }, 171 | "dependencies": { 172 | "supports-color": { 173 | "version": "5.5.0", 174 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 175 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 176 | "dev": true, 177 | "requires": { 178 | "has-flag": "^3.0.0" 179 | } 180 | } 181 | } 182 | }, 183 | "chokidar": { 184 | "version": "3.2.1", 185 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.2.1.tgz", 186 | "integrity": "sha512-/j5PPkb5Feyps9e+jo07jUZGvkB5Aj953NrI4s8xSVScrAo/RHeILrtdb4uzR7N6aaFFxxJ+gt8mA8HfNpw76w==", 187 | "dev": true, 188 | "requires": { 189 | "anymatch": "~3.1.1", 190 | "braces": "~3.0.2", 191 | "fsevents": "~2.1.0", 192 | "glob-parent": "~5.1.0", 193 | "is-binary-path": "~2.1.0", 194 | "is-glob": "~4.0.1", 195 | "normalize-path": "~3.0.0", 196 | "readdirp": "~3.1.3" 197 | } 198 | }, 199 | "chownr": { 200 | "version": "1.1.4", 201 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", 202 | "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", 203 | "dev": true 204 | }, 205 | "color-convert": { 206 | "version": "1.9.3", 207 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 208 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 209 | "dev": true, 210 | "requires": { 211 | "color-name": "1.1.3" 212 | } 213 | }, 214 | "color-name": { 215 | "version": "1.1.3", 216 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 217 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 218 | "dev": true 219 | }, 220 | "combined-stream": { 221 | "version": "1.0.8", 222 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 223 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 224 | "dev": true, 225 | "requires": { 226 | "delayed-stream": "~1.0.0" 227 | } 228 | }, 229 | "concat-map": { 230 | "version": "0.0.1", 231 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 232 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 233 | "dev": true 234 | }, 235 | "core-util-is": { 236 | "version": "1.0.2", 237 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 238 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 239 | "dev": true 240 | }, 241 | "cross-spawn": { 242 | "version": "7.0.0", 243 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.0.tgz", 244 | "integrity": "sha512-6U/8SMK2FBNnB21oQ4+6Nsodxanw1gTkntYA2zBdkFYFu3ZDx65P2ONEXGSvob/QS6REjVHQ9zxzdOafwFdstw==", 245 | "dev": true, 246 | "requires": { 247 | "path-key": "^3.1.0", 248 | "shebang-command": "^1.2.0", 249 | "which": "^1.2.9" 250 | }, 251 | "dependencies": { 252 | "which": { 253 | "version": "1.3.1", 254 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 255 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 256 | "dev": true, 257 | "requires": { 258 | "isexe": "^2.0.0" 259 | } 260 | } 261 | } 262 | }, 263 | "dashdash": { 264 | "version": "1.14.1", 265 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 266 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 267 | "dev": true, 268 | "requires": { 269 | "assert-plus": "^1.0.0" 270 | } 271 | }, 272 | "delayed-stream": { 273 | "version": "1.0.0", 274 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 275 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", 276 | "dev": true 277 | }, 278 | "ecc-jsbn": { 279 | "version": "0.1.2", 280 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 281 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 282 | "dev": true, 283 | "requires": { 284 | "jsbn": "~0.1.0", 285 | "safer-buffer": "^2.1.0" 286 | } 287 | }, 288 | "elm": { 289 | "version": "0.19.1-3", 290 | "resolved": "https://registry.npmjs.org/elm/-/elm-0.19.1-3.tgz", 291 | "integrity": "sha512-6y36ewCcVmTOx8lj7cKJs3bhI5qMfoVEigePZ9PhEUNKpwjjML/pU2u2YSpHVAznuCcojoF6KIsrS1Ci7GtVaQ==", 292 | "dev": true, 293 | "requires": { 294 | "request": "^2.88.0" 295 | } 296 | }, 297 | "elm-format": { 298 | "version": "0.8.3", 299 | "resolved": "https://registry.npmjs.org/elm-format/-/elm-format-0.8.3.tgz", 300 | "integrity": "sha512-shXOgfg8F5hDJagP91zJ3QT0PoMbusPfhgEeu3uRofTaN843cFpjZ8qlQip6pFQxtWyQE/P+NMg3vP6lyWI5Mg==", 301 | "dev": true, 302 | "requires": { 303 | "binwrap": "^0.2.2" 304 | } 305 | }, 306 | "elm-test": { 307 | "version": "0.19.1", 308 | "resolved": "https://registry.npmjs.org/elm-test/-/elm-test-0.19.1.tgz", 309 | "integrity": "sha512-SyZgZ/hxq62budS3k0M1Qj1E8fIRvldSxFSm4XfzE6qRRuHAT2a82fxprZRZl1yG2GwnImGmhuKH5hSyjPpzjA==", 310 | "dev": true, 311 | "requires": { 312 | "chalk": "2.4.2", 313 | "chokidar": "3.2.1", 314 | "cross-spawn": "7.0.0", 315 | "elmi-to-json": "1.2.0", 316 | "find-parent-dir": "^0.3.0", 317 | "firstline": "2.0.2", 318 | "fs-extra": "8.1.0", 319 | "glob": "7.1.4", 320 | "lodash": "4.17.15", 321 | "minimist": "^1.2.0", 322 | "murmur-hash-js": "1.0.0", 323 | "node-elm-compiler": "5.0.4", 324 | "split": "1.0.1", 325 | "supports-color": "7.1.0", 326 | "temp": "0.9.0", 327 | "which": "2.0.1", 328 | "xmlbuilder": "^13.0.2" 329 | } 330 | }, 331 | "elmi-to-json": { 332 | "version": "1.2.0", 333 | "resolved": "https://registry.npmjs.org/elmi-to-json/-/elmi-to-json-1.2.0.tgz", 334 | "integrity": "sha512-zNinzt6/YMr11HgeBlC9Z0UM3qHkYrGsWJTjrCmgBkKnaOLUzTP5K9N3z1RltyunItXtHAxb8DFPvMxlYRPv/Q==", 335 | "dev": true, 336 | "requires": { 337 | "binwrap": "0.2.2" 338 | } 339 | }, 340 | "escape-string-regexp": { 341 | "version": "1.0.5", 342 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 343 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 344 | "dev": true 345 | }, 346 | "extend": { 347 | "version": "3.0.2", 348 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 349 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", 350 | "dev": true 351 | }, 352 | "extsprintf": { 353 | "version": "1.3.0", 354 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 355 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", 356 | "dev": true 357 | }, 358 | "fast-deep-equal": { 359 | "version": "3.1.1", 360 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 361 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", 362 | "dev": true 363 | }, 364 | "fast-json-stable-stringify": { 365 | "version": "2.1.0", 366 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 367 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 368 | "dev": true 369 | }, 370 | "fill-range": { 371 | "version": "7.0.1", 372 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 373 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 374 | "dev": true, 375 | "requires": { 376 | "to-regex-range": "^5.0.1" 377 | } 378 | }, 379 | "find-elm-dependencies": { 380 | "version": "2.0.2", 381 | "resolved": "https://registry.npmjs.org/find-elm-dependencies/-/find-elm-dependencies-2.0.2.tgz", 382 | "integrity": "sha512-nM5UCbccD1G8CGK2GsM7ykG3ksOAl9E+34jiDfl07CAl2OPnLpBVWY2hlxEmIkSBfdJjSopEowWHrO0cI8RhxQ==", 383 | "dev": true, 384 | "requires": { 385 | "firstline": "1.2.0", 386 | "lodash": "4.17.15" 387 | }, 388 | "dependencies": { 389 | "firstline": { 390 | "version": "1.2.0", 391 | "resolved": "https://registry.npmjs.org/firstline/-/firstline-1.2.0.tgz", 392 | "integrity": "sha1-yfSIbn9/vwr8EtcZQdzgaxkq6gU=", 393 | "dev": true 394 | } 395 | } 396 | }, 397 | "find-parent-dir": { 398 | "version": "0.3.0", 399 | "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", 400 | "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", 401 | "dev": true 402 | }, 403 | "firstline": { 404 | "version": "2.0.2", 405 | "resolved": "https://registry.npmjs.org/firstline/-/firstline-2.0.2.tgz", 406 | "integrity": "sha512-8KcmfI0jgSECnzdhucm0i7vrwef3BWwgjimW2YkRC5eSFwjb5DibVoA0YvgkYwwxuJi9c+7M7X3b3lX8o9B6wg==", 407 | "dev": true 408 | }, 409 | "forever-agent": { 410 | "version": "0.6.1", 411 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 412 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", 413 | "dev": true 414 | }, 415 | "form-data": { 416 | "version": "2.3.3", 417 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 418 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 419 | "dev": true, 420 | "requires": { 421 | "asynckit": "^0.4.0", 422 | "combined-stream": "^1.0.6", 423 | "mime-types": "^2.1.12" 424 | } 425 | }, 426 | "fs-extra": { 427 | "version": "8.1.0", 428 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 429 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 430 | "dev": true, 431 | "requires": { 432 | "graceful-fs": "^4.2.0", 433 | "jsonfile": "^4.0.0", 434 | "universalify": "^0.1.0" 435 | } 436 | }, 437 | "fs-minipass": { 438 | "version": "1.2.7", 439 | "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", 440 | "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", 441 | "dev": true, 442 | "requires": { 443 | "minipass": "^2.6.0" 444 | } 445 | }, 446 | "fs.realpath": { 447 | "version": "1.0.0", 448 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 449 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 450 | "dev": true 451 | }, 452 | "fsevents": { 453 | "version": "2.1.3", 454 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", 455 | "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", 456 | "dev": true, 457 | "optional": true 458 | }, 459 | "getpass": { 460 | "version": "0.1.7", 461 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 462 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 463 | "dev": true, 464 | "requires": { 465 | "assert-plus": "^1.0.0" 466 | } 467 | }, 468 | "glob": { 469 | "version": "7.1.4", 470 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", 471 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", 472 | "dev": true, 473 | "requires": { 474 | "fs.realpath": "^1.0.0", 475 | "inflight": "^1.0.4", 476 | "inherits": "2", 477 | "minimatch": "^3.0.4", 478 | "once": "^1.3.0", 479 | "path-is-absolute": "^1.0.0" 480 | } 481 | }, 482 | "glob-parent": { 483 | "version": "5.1.1", 484 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", 485 | "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", 486 | "dev": true, 487 | "requires": { 488 | "is-glob": "^4.0.1" 489 | } 490 | }, 491 | "graceful-fs": { 492 | "version": "4.2.4", 493 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 494 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 495 | "dev": true 496 | }, 497 | "har-schema": { 498 | "version": "2.0.0", 499 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 500 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", 501 | "dev": true 502 | }, 503 | "har-validator": { 504 | "version": "5.1.3", 505 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 506 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 507 | "dev": true, 508 | "requires": { 509 | "ajv": "^6.5.5", 510 | "har-schema": "^2.0.0" 511 | } 512 | }, 513 | "has-flag": { 514 | "version": "3.0.0", 515 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 516 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 517 | "dev": true 518 | }, 519 | "http-signature": { 520 | "version": "1.2.0", 521 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 522 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 523 | "dev": true, 524 | "requires": { 525 | "assert-plus": "^1.0.0", 526 | "jsprim": "^1.2.2", 527 | "sshpk": "^1.7.0" 528 | } 529 | }, 530 | "inflight": { 531 | "version": "1.0.6", 532 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 533 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 534 | "dev": true, 535 | "requires": { 536 | "once": "^1.3.0", 537 | "wrappy": "1" 538 | } 539 | }, 540 | "inherits": { 541 | "version": "2.0.4", 542 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 543 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 544 | "dev": true 545 | }, 546 | "is-binary-path": { 547 | "version": "2.1.0", 548 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 549 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 550 | "dev": true, 551 | "requires": { 552 | "binary-extensions": "^2.0.0" 553 | } 554 | }, 555 | "is-extglob": { 556 | "version": "2.1.1", 557 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 558 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 559 | "dev": true 560 | }, 561 | "is-glob": { 562 | "version": "4.0.1", 563 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 564 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 565 | "dev": true, 566 | "requires": { 567 | "is-extglob": "^2.1.1" 568 | } 569 | }, 570 | "is-number": { 571 | "version": "7.0.0", 572 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 573 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 574 | "dev": true 575 | }, 576 | "is-typedarray": { 577 | "version": "1.0.0", 578 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 579 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", 580 | "dev": true 581 | }, 582 | "isexe": { 583 | "version": "2.0.0", 584 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 585 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 586 | "dev": true 587 | }, 588 | "isstream": { 589 | "version": "0.1.2", 590 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 591 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", 592 | "dev": true 593 | }, 594 | "jsbn": { 595 | "version": "0.1.1", 596 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 597 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 598 | "dev": true 599 | }, 600 | "json-schema": { 601 | "version": "0.2.3", 602 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 603 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", 604 | "dev": true 605 | }, 606 | "json-schema-traverse": { 607 | "version": "0.4.1", 608 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 609 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 610 | "dev": true 611 | }, 612 | "json-stringify-safe": { 613 | "version": "5.0.1", 614 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 615 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 616 | "dev": true 617 | }, 618 | "jsonfile": { 619 | "version": "4.0.0", 620 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 621 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 622 | "dev": true, 623 | "requires": { 624 | "graceful-fs": "^4.1.6" 625 | } 626 | }, 627 | "jsprim": { 628 | "version": "1.4.1", 629 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 630 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 631 | "dev": true, 632 | "requires": { 633 | "assert-plus": "1.0.0", 634 | "extsprintf": "1.3.0", 635 | "json-schema": "0.2.3", 636 | "verror": "1.10.0" 637 | } 638 | }, 639 | "lodash": { 640 | "version": "4.17.15", 641 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 642 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 643 | "dev": true 644 | }, 645 | "mime-db": { 646 | "version": "1.44.0", 647 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 648 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", 649 | "dev": true 650 | }, 651 | "mime-types": { 652 | "version": "2.1.27", 653 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 654 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 655 | "dev": true, 656 | "requires": { 657 | "mime-db": "1.44.0" 658 | } 659 | }, 660 | "minimatch": { 661 | "version": "3.0.4", 662 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 663 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 664 | "dev": true, 665 | "requires": { 666 | "brace-expansion": "^1.1.7" 667 | } 668 | }, 669 | "minimist": { 670 | "version": "1.2.5", 671 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 672 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 673 | "dev": true 674 | }, 675 | "minipass": { 676 | "version": "2.9.0", 677 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", 678 | "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", 679 | "dev": true, 680 | "requires": { 681 | "safe-buffer": "^5.1.2", 682 | "yallist": "^3.0.0" 683 | } 684 | }, 685 | "minizlib": { 686 | "version": "1.3.3", 687 | "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", 688 | "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", 689 | "dev": true, 690 | "requires": { 691 | "minipass": "^2.9.0" 692 | } 693 | }, 694 | "mkdirp": { 695 | "version": "0.5.5", 696 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 697 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 698 | "dev": true, 699 | "requires": { 700 | "minimist": "^1.2.5" 701 | } 702 | }, 703 | "murmur-hash-js": { 704 | "version": "1.0.0", 705 | "resolved": "https://registry.npmjs.org/murmur-hash-js/-/murmur-hash-js-1.0.0.tgz", 706 | "integrity": "sha1-UEEEkmnJZjPIZjhpYLL0KJ515bA=", 707 | "dev": true 708 | }, 709 | "mustache": { 710 | "version": "3.2.1", 711 | "resolved": "https://registry.npmjs.org/mustache/-/mustache-3.2.1.tgz", 712 | "integrity": "sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==", 713 | "dev": true 714 | }, 715 | "nice-try": { 716 | "version": "1.0.5", 717 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 718 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 719 | "dev": true 720 | }, 721 | "node-elm-compiler": { 722 | "version": "5.0.4", 723 | "resolved": "https://registry.npmjs.org/node-elm-compiler/-/node-elm-compiler-5.0.4.tgz", 724 | "integrity": "sha512-VQsT8QSierYGkHzRed+b4MnccQVF1+qPHunE8jBoU7jD6YpuRqCDPzEoC2zfyEJS80qVnlMZrqobLnyjzX9lJg==", 725 | "dev": true, 726 | "requires": { 727 | "cross-spawn": "6.0.5", 728 | "find-elm-dependencies": "2.0.2", 729 | "lodash": "4.17.15", 730 | "temp": "^0.9.0" 731 | }, 732 | "dependencies": { 733 | "cross-spawn": { 734 | "version": "6.0.5", 735 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 736 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 737 | "dev": true, 738 | "requires": { 739 | "nice-try": "^1.0.4", 740 | "path-key": "^2.0.1", 741 | "semver": "^5.5.0", 742 | "shebang-command": "^1.2.0", 743 | "which": "^1.2.9" 744 | } 745 | }, 746 | "path-key": { 747 | "version": "2.0.1", 748 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 749 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 750 | "dev": true 751 | }, 752 | "temp": { 753 | "version": "0.9.1", 754 | "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.1.tgz", 755 | "integrity": "sha512-WMuOgiua1xb5R56lE0eH6ivpVmg/lq2OHm4+LtT/xtEtPQ+sz6N3bBM6WZ5FvO1lO4IKIOb43qnhoc4qxP5OeA==", 756 | "dev": true, 757 | "requires": { 758 | "rimraf": "~2.6.2" 759 | } 760 | }, 761 | "which": { 762 | "version": "1.3.1", 763 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 764 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 765 | "dev": true, 766 | "requires": { 767 | "isexe": "^2.0.0" 768 | } 769 | } 770 | } 771 | }, 772 | "normalize-path": { 773 | "version": "3.0.0", 774 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 775 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 776 | "dev": true 777 | }, 778 | "oauth-sign": { 779 | "version": "0.9.0", 780 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 781 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", 782 | "dev": true 783 | }, 784 | "once": { 785 | "version": "1.4.0", 786 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 787 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 788 | "dev": true, 789 | "requires": { 790 | "wrappy": "1" 791 | } 792 | }, 793 | "path-is-absolute": { 794 | "version": "1.0.1", 795 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 796 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 797 | "dev": true 798 | }, 799 | "path-key": { 800 | "version": "3.1.1", 801 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 802 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 803 | "dev": true 804 | }, 805 | "performance-now": { 806 | "version": "2.1.0", 807 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 808 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", 809 | "dev": true 810 | }, 811 | "picomatch": { 812 | "version": "2.2.2", 813 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", 814 | "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", 815 | "dev": true 816 | }, 817 | "psl": { 818 | "version": "1.8.0", 819 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 820 | "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", 821 | "dev": true 822 | }, 823 | "punycode": { 824 | "version": "2.1.1", 825 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 826 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 827 | "dev": true 828 | }, 829 | "qs": { 830 | "version": "6.5.2", 831 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 832 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", 833 | "dev": true 834 | }, 835 | "readdirp": { 836 | "version": "3.1.3", 837 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.3.tgz", 838 | "integrity": "sha512-ZOsfTGkjO2kqeR5Mzr5RYDbTGYneSkdNKX2fOX2P5jF7vMrd/GNnIAUtDldeHHumHUCQ3V05YfWUdxMPAsRu9Q==", 839 | "dev": true, 840 | "requires": { 841 | "picomatch": "^2.0.4" 842 | } 843 | }, 844 | "request": { 845 | "version": "2.88.2", 846 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", 847 | "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", 848 | "dev": true, 849 | "requires": { 850 | "aws-sign2": "~0.7.0", 851 | "aws4": "^1.8.0", 852 | "caseless": "~0.12.0", 853 | "combined-stream": "~1.0.6", 854 | "extend": "~3.0.2", 855 | "forever-agent": "~0.6.1", 856 | "form-data": "~2.3.2", 857 | "har-validator": "~5.1.3", 858 | "http-signature": "~1.2.0", 859 | "is-typedarray": "~1.0.0", 860 | "isstream": "~0.1.2", 861 | "json-stringify-safe": "~5.0.1", 862 | "mime-types": "~2.1.19", 863 | "oauth-sign": "~0.9.0", 864 | "performance-now": "^2.1.0", 865 | "qs": "~6.5.2", 866 | "safe-buffer": "^5.1.2", 867 | "tough-cookie": "~2.5.0", 868 | "tunnel-agent": "^0.6.0", 869 | "uuid": "^3.3.2" 870 | } 871 | }, 872 | "request-promise": { 873 | "version": "4.2.5", 874 | "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz", 875 | "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==", 876 | "dev": true, 877 | "requires": { 878 | "bluebird": "^3.5.0", 879 | "request-promise-core": "1.1.3", 880 | "stealthy-require": "^1.1.1", 881 | "tough-cookie": "^2.3.3" 882 | } 883 | }, 884 | "request-promise-core": { 885 | "version": "1.1.3", 886 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", 887 | "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", 888 | "dev": true, 889 | "requires": { 890 | "lodash": "^4.17.15" 891 | } 892 | }, 893 | "rimraf": { 894 | "version": "2.6.3", 895 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 896 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 897 | "dev": true, 898 | "requires": { 899 | "glob": "^7.1.3" 900 | } 901 | }, 902 | "safe-buffer": { 903 | "version": "5.2.1", 904 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 905 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 906 | "dev": true 907 | }, 908 | "safer-buffer": { 909 | "version": "2.1.2", 910 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 911 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 912 | "dev": true 913 | }, 914 | "semver": { 915 | "version": "5.7.1", 916 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 917 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 918 | "dev": true 919 | }, 920 | "shebang-command": { 921 | "version": "1.2.0", 922 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 923 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 924 | "dev": true, 925 | "requires": { 926 | "shebang-regex": "^1.0.0" 927 | } 928 | }, 929 | "shebang-regex": { 930 | "version": "1.0.0", 931 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 932 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 933 | "dev": true 934 | }, 935 | "split": { 936 | "version": "1.0.1", 937 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", 938 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", 939 | "dev": true, 940 | "requires": { 941 | "through": "2" 942 | } 943 | }, 944 | "sshpk": { 945 | "version": "1.16.1", 946 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 947 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 948 | "dev": true, 949 | "requires": { 950 | "asn1": "~0.2.3", 951 | "assert-plus": "^1.0.0", 952 | "bcrypt-pbkdf": "^1.0.0", 953 | "dashdash": "^1.12.0", 954 | "ecc-jsbn": "~0.1.1", 955 | "getpass": "^0.1.1", 956 | "jsbn": "~0.1.0", 957 | "safer-buffer": "^2.0.2", 958 | "tweetnacl": "~0.14.0" 959 | } 960 | }, 961 | "stealthy-require": { 962 | "version": "1.1.1", 963 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", 964 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", 965 | "dev": true 966 | }, 967 | "supports-color": { 968 | "version": "7.1.0", 969 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", 970 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", 971 | "dev": true, 972 | "requires": { 973 | "has-flag": "^4.0.0" 974 | }, 975 | "dependencies": { 976 | "has-flag": { 977 | "version": "4.0.0", 978 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 979 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 980 | "dev": true 981 | } 982 | } 983 | }, 984 | "tar": { 985 | "version": "4.4.13", 986 | "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", 987 | "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", 988 | "dev": true, 989 | "requires": { 990 | "chownr": "^1.1.1", 991 | "fs-minipass": "^1.2.5", 992 | "minipass": "^2.8.6", 993 | "minizlib": "^1.2.1", 994 | "mkdirp": "^0.5.0", 995 | "safe-buffer": "^5.1.2", 996 | "yallist": "^3.0.3" 997 | } 998 | }, 999 | "temp": { 1000 | "version": "0.9.0", 1001 | "resolved": "https://registry.npmjs.org/temp/-/temp-0.9.0.tgz", 1002 | "integrity": "sha512-YfUhPQCJoNQE5N+FJQcdPz63O3x3sdT4Xju69Gj4iZe0lBKOtnAMi0SLj9xKhGkcGhsxThvTJ/usxtFPo438zQ==", 1003 | "dev": true, 1004 | "requires": { 1005 | "rimraf": "~2.6.2" 1006 | } 1007 | }, 1008 | "through": { 1009 | "version": "2.3.8", 1010 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1011 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 1012 | "dev": true 1013 | }, 1014 | "to-regex-range": { 1015 | "version": "5.0.1", 1016 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1017 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1018 | "dev": true, 1019 | "requires": { 1020 | "is-number": "^7.0.0" 1021 | } 1022 | }, 1023 | "tough-cookie": { 1024 | "version": "2.5.0", 1025 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 1026 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 1027 | "dev": true, 1028 | "requires": { 1029 | "psl": "^1.1.28", 1030 | "punycode": "^2.1.1" 1031 | } 1032 | }, 1033 | "traverse": { 1034 | "version": "0.3.9", 1035 | "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", 1036 | "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", 1037 | "dev": true 1038 | }, 1039 | "tunnel-agent": { 1040 | "version": "0.6.0", 1041 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1042 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1043 | "dev": true, 1044 | "requires": { 1045 | "safe-buffer": "^5.0.1" 1046 | } 1047 | }, 1048 | "tweetnacl": { 1049 | "version": "0.14.5", 1050 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1051 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 1052 | "dev": true 1053 | }, 1054 | "universalify": { 1055 | "version": "0.1.2", 1056 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1057 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1058 | "dev": true 1059 | }, 1060 | "unzip-stream": { 1061 | "version": "0.3.0", 1062 | "resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.0.tgz", 1063 | "integrity": "sha512-NG1h/MdGIX3HzyqMjyj1laBCmlPYhcO4xEy7gEqqzGiSLw7XqDQCnY4nYSn5XSaH8mQ6TFkaujrO8d/PIZN85A==", 1064 | "dev": true, 1065 | "requires": { 1066 | "binary": "^0.3.0", 1067 | "mkdirp": "^0.5.1" 1068 | } 1069 | }, 1070 | "uri-js": { 1071 | "version": "4.2.2", 1072 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1073 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1074 | "dev": true, 1075 | "requires": { 1076 | "punycode": "^2.1.0" 1077 | } 1078 | }, 1079 | "uuid": { 1080 | "version": "3.4.0", 1081 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", 1082 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", 1083 | "dev": true 1084 | }, 1085 | "verror": { 1086 | "version": "1.10.0", 1087 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1088 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1089 | "dev": true, 1090 | "requires": { 1091 | "assert-plus": "^1.0.0", 1092 | "core-util-is": "1.0.2", 1093 | "extsprintf": "^1.2.0" 1094 | } 1095 | }, 1096 | "which": { 1097 | "version": "2.0.1", 1098 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.1.tgz", 1099 | "integrity": "sha512-N7GBZOTswtB9lkQBZA4+zAXrjEIWAUOB93AvzUiudRzRxhUdLURQ7D/gAIMY1gatT/LTbmbcv8SiYazy3eYB7w==", 1100 | "dev": true, 1101 | "requires": { 1102 | "isexe": "^2.0.0" 1103 | } 1104 | }, 1105 | "wrappy": { 1106 | "version": "1.0.2", 1107 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1108 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1109 | "dev": true 1110 | }, 1111 | "xmlbuilder": { 1112 | "version": "13.0.2", 1113 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz", 1114 | "integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==", 1115 | "dev": true 1116 | }, 1117 | "yallist": { 1118 | "version": "3.1.1", 1119 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", 1120 | "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", 1121 | "dev": true 1122 | } 1123 | } 1124 | } 1125 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elm-obj-loader", 3 | "version": "1.0.1", 4 | "description": "Load Wavefront .obj files in your WebGL scene.", 5 | "main": "index.js", 6 | "repository": "git@github.com:declension/elm-obj-loader.git", 7 | "author": "Nick B ", 8 | "license": "MIT", 9 | "private": false, 10 | "devDependencies": { 11 | "elm": "^0.19.1-3", 12 | "elm-format": "^0.8.3", 13 | "elm-test": "0.19.1" 14 | }, 15 | "scripts": { 16 | "test": "elm-test tests", 17 | "elm": "node_modules/.bin/elm", 18 | "clean": "rm -rf dist/", 19 | "build-examples": "npm run clean && cp -r examples/ dist/ && cd dist && npx elm make Suzanne.elm --output suzanne.html && npx elm make ModelViewer.elm --output model-viewer.html && rm -rf *.elm elm-stuff/" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/OBJ.elm: -------------------------------------------------------------------------------- 1 | module OBJ exposing 2 | ( loadMeshWithoutTexture, loadMesh, loadMeshWithTangent 3 | , loadObjFile, loadObjFileWith, Settings, defaultSettings 4 | , parseObjStringWith 5 | ) 6 | 7 | {-| 8 | 9 | 10 | # .obj file loader 11 | 12 | The returned models can be rendered using `indexedTriangles` from `WebGL`. 13 | 14 | WebGL.indexedTriangles mesh.vertices mesh.indices 15 | 16 | 17 | ## From URL 18 | 19 | All these methods take an URL as the first parameter. 20 | 21 | 22 | ### Single model 23 | 24 | Use the methods from here if you know whats in your file 25 | and if they only contain a single object with a single material. 26 | These are just provided for convenience. 27 | 28 | @docs loadMeshWithoutTexture, loadMesh, loadMeshWithTangent 29 | 30 | 31 | ### General 32 | 33 | Use these methods if you don't know what kind of files you'll get or 34 | if your files contain multiple groups or materials. 35 | 36 | @docs loadObjFile, loadObjFileWith, Settings, defaultSettings 37 | 38 | 39 | ## From String 40 | 41 | @docs parseObjStringWith 42 | 43 | -} 44 | 45 | import Dict exposing (Dict) 46 | import Http exposing (Response) 47 | import OBJ.Assembler exposing (compile) 48 | import OBJ.Parser exposing (parse) 49 | import OBJ.Types exposing (..) 50 | import String exposing (fromInt) 51 | import Task 52 | 53 | 54 | {-| Load a model that doesn't have texture coordinates. 55 | -} 56 | loadMeshWithoutTexture : String -> (Result String (MeshWith Vertex) -> msg) -> Cmd msg 57 | loadMeshWithoutTexture url msg = 58 | loadObjFile url 59 | (\res -> 60 | case res of 61 | Ok f -> 62 | case Dict.values f |> List.map Dict.values of 63 | [ [ WithoutTexture m ] ] -> 64 | msg (Ok m) 65 | 66 | _ -> 67 | msg (Err "file loaded correctly, but there were more than one models.") 68 | 69 | Err e -> 70 | msg (Err e) 71 | ) 72 | 73 | 74 | {-| Load a model with texture coordinates. 75 | -} 76 | loadMesh : String -> (Result String (MeshWith VertexWithTexture) -> msg) -> Cmd msg 77 | loadMesh url msg = 78 | loadObjFile url 79 | (\res -> 80 | case res of 81 | Ok f -> 82 | case Dict.values f |> List.map Dict.values of 83 | [ [ WithTexture m ] ] -> 84 | msg (Ok m) 85 | 86 | _ -> 87 | msg (Err "file loaded correctly, but there were more than one models.") 88 | 89 | Err e -> 90 | msg (Err e) 91 | ) 92 | 93 | 94 | {-| Load a model with texture coordinate and calculate vertex tangents. 95 | This is needed if you want to do tangent space normal mapping. 96 | -} 97 | loadMeshWithTangent : String -> (Result String (MeshWith VertexWithTextureAndTangent) -> msg) -> Cmd msg 98 | loadMeshWithTangent url msg = 99 | loadObjFileWith { withTangents = True } 100 | url 101 | (\res -> 102 | case res of 103 | Ok f -> 104 | case Dict.values f |> List.map Dict.values of 105 | [ [ WithTextureAndTangent m ] ] -> 106 | msg (Ok m) 107 | 108 | _ -> 109 | msg (Err "file loaded correctly, but there were more than one models.") 110 | 111 | Err e -> 112 | msg (Err e) 113 | ) 114 | 115 | 116 | {-| Load a .obj file from an URL 117 | 118 | loadObjFile url ObjFileLoaded 119 | 120 | -} 121 | loadObjFile : String -> (Result String ObjFile -> msg) -> Cmd msg 122 | loadObjFile = 123 | loadObjFileWith defaultSettings 124 | 125 | 126 | {-| withTangents : If true, vertex tangents will be calculated for meshes with texture coordinates. 127 | This is needed if you want to do tangent space normal mapping. 128 | -} 129 | type alias Settings = 130 | { withTangents : Bool } 131 | 132 | 133 | {-| -} 134 | defaultSettings : Settings 135 | defaultSettings = 136 | { withTangents = False } 137 | 138 | 139 | {-| -} 140 | loadObjFileWith : Settings -> String -> (Result String ObjFile -> msg) -> Cmd msg 141 | loadObjFileWith settings url msg = 142 | Http.toTask (Http.getString url) 143 | |> Task.andThen 144 | (\s -> 145 | parseObjStringWith settings s |> Task.succeed 146 | ) 147 | |> Task.onError (\e -> Task.succeed (Err <| httpErrorFor e)) 148 | |> Task.attempt 149 | (\r -> 150 | case r of 151 | Ok (Ok m) -> 152 | msg (Ok m) 153 | 154 | Ok (Err e) -> 155 | msg (Err e) 156 | 157 | Err e -> 158 | msg (Err e) 159 | ) 160 | 161 | 162 | {-| Same as `loadObjFile`, but works on a string. 163 | -} 164 | parseObjStringWith : Settings -> String -> Result String ObjFile 165 | parseObjStringWith config input = 166 | parse input 167 | |> Result.map (compile config) 168 | 169 | 170 | httpErrorFor : Http.Error -> String 171 | httpErrorFor e = 172 | case e of 173 | Http.BadUrl url -> 174 | "Bad URL: " ++ url 175 | 176 | Http.Timeout -> 177 | "Timed out" 178 | 179 | Http.NetworkError -> 180 | "Network error" 181 | 182 | Http.BadStatus response -> 183 | "Failed" 184 | 185 | Http.BadPayload string response -> 186 | fromInt response.status.code ++ ": invalid request in " ++ response.body 187 | -------------------------------------------------------------------------------- /src/OBJ/Assembler.elm: -------------------------------------------------------------------------------- 1 | module OBJ.Assembler exposing (addCurrentGroup, addCurrentMesh, addFace, addFaceToMesh, applyForFace, applyForFaceA, arrayUpdate, compile, compileHelper, createMesh, emptyCompileState, finalizeMesh, fst2, get2, get3, getFaceTangent, getOrInsertVN, getOrInsertVTN, getOrInsertVTNT, insertLine, t3map, triangulate, triangulateFace, updateArray) 2 | 3 | import Array exposing (Array) 4 | import Dict exposing (Dict) 5 | import Math.Vector2 as V2 exposing (Vec2) 6 | import Math.Vector3 as V3 exposing (Vec3, vec3) 7 | import Math.Vector4 as V4 exposing (Vec4, vec4) 8 | import OBJ.InternalTypes exposing (..) 9 | import OBJ.Types exposing (..) 10 | 11 | 12 | compile config lines = 13 | compileHelper (emptyCompileState config) lines 14 | |> addCurrentMesh 15 | |> addCurrentGroup 16 | |> .groups 17 | 18 | 19 | emptyCompileState config = 20 | { -- this is a Dict (GroupName/String) Group 21 | -- it's the final output of this algorithm 22 | -- Group = Dict (MtlName/String) Mesh 23 | groups = Dict.empty 24 | , currentGroupName = "__default__" 25 | , currentMaterialName = "__default__" 26 | , currentMesh = Nothing 27 | , currentGroup = Dict.empty 28 | , vs = Array.empty 29 | , vts = Array.empty 30 | , vns = Array.empty 31 | , currentIndex = 0 32 | , knownVertexTextures = Dict.empty 33 | , knownVertexTexturesTangents = Dict.empty 34 | , knownVertex = Dict.empty 35 | , config = config 36 | } 37 | 38 | 39 | compileHelper state lines = 40 | case lines of 41 | [] -> 42 | state 43 | 44 | l :: ls -> 45 | compileHelper (insertLine l state) ls 46 | 47 | 48 | {-| This 'inserts' a line into the state. 49 | This means it manipulates the current state to reflect state changing commands 50 | and builds meshes on the fly. 51 | -} 52 | insertLine line state = 53 | case line of 54 | Object s -> 55 | -- even though the specs doesn't give it any meaningful meaning, 56 | -- I treat is exactly like a group statement. 57 | -- This is because blender uses o instead of g per default. 58 | addCurrentGroup state 59 | |> (\st -> { st | currentGroupName = s }) 60 | 61 | MtlLib s -> 62 | -- MtlLib statements are ignored, 63 | -- as I don't plan to support loading .mtl files 64 | state 65 | 66 | Group s -> 67 | addCurrentGroup state 68 | |> (\st -> { st | currentGroupName = s }) 69 | 70 | Smooth s -> 71 | -- smooth groups are ignored. 72 | -- I tried to calculate these, but failed, 73 | -- since doing them correctly is more tricky than you might think: 74 | -- http://www.bytehazard.com/articles/vertnorm.html 75 | -- { state | activeSmoothGroup = s } 76 | state 77 | 78 | UseMtl s -> 79 | addCurrentMesh state 80 | |> (\st -> { st | currentMaterialName = s }) 81 | 82 | V v -> 83 | { state | vs = Array.push v state.vs } 84 | 85 | Vt v -> 86 | { state | vts = Array.push v state.vts } 87 | 88 | Vn v -> 89 | { state | vns = Array.push v state.vns } 90 | 91 | F f -> 92 | triangulateFace f 93 | |> List.foldr addFace state 94 | 95 | 96 | triangulateFace f = 97 | case f of 98 | FVertexTextureNormal a -> 99 | triangulate a |> List.map FTVertexTextureNormal 100 | 101 | FVertexNormal a -> 102 | triangulate a |> List.map FTVertexNormal 103 | 104 | 105 | addCurrentMesh state = 106 | -- Adds the current mesh to the current group. 107 | -- We also normalize all values here that need normalizing 108 | case state.currentMesh of 109 | Just m -> 110 | { state 111 | | currentGroup = Dict.insert state.currentMaterialName (finalizeMesh m) state.currentGroup 112 | , currentMesh = Nothing 113 | , knownVertexTextures = Dict.empty 114 | , knownVertexTexturesTangents = Dict.empty 115 | , knownVertex = Dict.empty 116 | } 117 | 118 | _ -> 119 | state 120 | 121 | 122 | finalizeMesh : MeshT -> Mesh 123 | finalizeMesh mesh = 124 | case mesh of 125 | WithTextureT m -> 126 | WithTexture m 127 | 128 | WithoutTextureT m -> 129 | WithoutTexture m 130 | 131 | WithTextureAndTangentT m -> 132 | WithTextureAndTangent { indices = m.indices, vertices = Array.foldr reducer [] m.vertices } 133 | 134 | 135 | reducer : VertexWithTextureAndTangentT -> List VertexWithTextureAndTangent -> List VertexWithTextureAndTangent 136 | reducer { position, texCoord, normal, sdir, tdir } acc = 137 | let 138 | -- handedness: 139 | -- https://web.archive.org/web/20160409104130/http://www.terathon.com/code/tangent.html 140 | w = 141 | if V3.dot (V3.cross normal sdir) tdir < 0 then 142 | -1 143 | 144 | else 145 | 1 146 | 147 | { x, y, z } = 148 | -- I have not seen this anywhere, but I added it because I sometimes got (0,0,0) 149 | if V3.lengthSquared sdir /= 0 then 150 | V3.toRecord <| V3.normalize (V3.sub sdir (V3.scale (V3.dot normal sdir) normal)) 151 | 152 | else 153 | V3.toRecord <| V3.cross (V3.normalize (V3.sub tdir (V3.scale (V3.dot normal tdir) normal))) normal 154 | in 155 | { position = position 156 | , texCoord = texCoord 157 | , normal = normal 158 | , tangent = vec4 x y z w 159 | } 160 | :: acc 161 | 162 | 163 | addCurrentGroup state = 164 | if Dict.isEmpty state.currentGroup then 165 | state 166 | 167 | else 168 | { state 169 | | groups = Dict.insert state.currentGroupName state.currentGroup state.groups 170 | , currentGroup = Dict.empty 171 | } 172 | 173 | 174 | addFace f state = 175 | -- this function adds a single face to the currentMesh 176 | -- for this it needs a dictionary containing the already known vertices, 177 | -- indexed using the v/vn etc. 178 | case state.currentMesh of 179 | Nothing -> 180 | -- we dont have a mesh yet, create one based on the type of the face 181 | addFaceToMesh f (createMesh state.config.withTangents f) { state | currentIndex = 0 } 182 | 183 | Just m -> 184 | addFaceToMesh f m state 185 | 186 | 187 | addFaceToMesh f mesh ({ vs, vts, vns, currentIndex } as state) = 188 | -- add a face to the mesh 189 | case ( f, mesh ) of 190 | ( FTVertexTextureNormal ( v1, v2, v3 ), WithTextureT m ) -> 191 | let 192 | ( newState, newVs, newIs ) = 193 | applyForFace getOrInsertVTN ( v1, v2, v3 ) state 194 | 195 | newMesh = 196 | WithTextureT { m | indices = newIs :: m.indices, vertices = m.vertices ++ newVs } 197 | in 198 | { newState | currentMesh = Just newMesh } 199 | 200 | ( FTVertexTextureNormal ( v1, v2, v3 ), WithTextureAndTangentT m ) -> 201 | let 202 | tangents = 203 | getFaceTangent ( v1, v2, v3 ) state 204 | 205 | ( newState, newVs, newIs ) = 206 | applyForFaceA (getOrInsertVTNT tangents) ( v1, v2, v3 ) state 207 | 208 | newMesh = 209 | WithTextureAndTangentT { m | indices = newIs :: m.indices, vertices = Array.append m.vertices newVs } 210 | in 211 | { newState | currentMesh = Just newMesh } 212 | 213 | ( FTVertexNormal ( v1, v2, v3 ), WithoutTextureT m ) -> 214 | let 215 | ( newState, newVs, newIs ) = 216 | applyForFace getOrInsertVN ( v1, v2, v3 ) state 217 | 218 | newMesh = 219 | WithoutTextureT { m | indices = newIs :: m.indices, vertices = m.vertices ++ newVs } 220 | in 221 | { newState | currentMesh = Just newMesh } 222 | 223 | _ -> 224 | -- TODO: lift this error into a Result type 225 | { config = { withTangents = False } 226 | , currentMesh = Nothing 227 | , currentGroup = Dict.empty 228 | , currentGroupName = "(error)" 229 | , currentMaterialName = "(error)" 230 | , vs = Array.empty 231 | , vts = Array.empty 232 | , vns = Array.empty 233 | , groups = Dict.empty 234 | , currentIndex = 0 235 | , knownVertexTextures = Dict.empty 236 | , knownVertexTexturesTangents = Dict.empty 237 | , knownVertex = Dict.empty 238 | } 239 | 240 | 241 | applyForFace f ( i1, i2, i3 ) s_0 = 242 | let 243 | ( s_1, vs_1, i_1 ) = 244 | f i1 s_0 245 | 246 | ( s_2, vs_2, i_2 ) = 247 | f i2 s_1 248 | 249 | ( s_3, vs_3, i_3 ) = 250 | f i3 s_2 251 | in 252 | ( s_3, vs_1 ++ vs_2 ++ vs_3, ( i_3, i_2, i_1 ) ) 253 | 254 | 255 | applyForFaceA f ( i1, i2, i3 ) s_0 = 256 | let 257 | ( s_1, vs_1, i_1 ) = 258 | f i1 s_0 259 | 260 | ( s_2, vs_2, i_2 ) = 261 | f i2 s_1 262 | 263 | ( s_3, vs_3, i_3 ) = 264 | f i3 s_2 265 | in 266 | ( s_3, Array.append (Array.append vs_1 vs_2) vs_3, ( i_3, i_2, i_1 ) ) 267 | 268 | 269 | getFaceTangent (( ( pi1, ti1, ni1 ), ( pi2, ti2, ni2 ), ( pi3, ti3, ni3 ) ) as index) { vs, vts, vns } = 270 | -- This is from here: 271 | -- https://web.archive.org/web/20160409104130/http://www.terathon.com/code/tangent.html 272 | -- But since the reference doesn't mention what to do in case the denominator is 0, 273 | -- This is probably not correct. 274 | case ( get3 ( pi1, pi2, pi3 ) vs vs vs, get3 ( ti1, ti2, ti3 ) vts vts vts ) of 275 | ( Just ( v1, v2, v3 ), Just ( w1, w2, w3 ) ) -> 276 | let 277 | ( vv1, vv2, vv3 ) = 278 | t3map V3.toRecord ( v1, v2, v3 ) 279 | 280 | ( ww1, ww2, ww3 ) = 281 | t3map V2.toRecord ( w1, w2, w3 ) 282 | 283 | ( ( x1, x2 ), ( y1, y2 ), ( z1, z2 ) ) = 284 | ( ( vv2.x - vv1.x, vv3.x - vv1.x ) 285 | , ( vv2.y - vv1.y, vv3.y - vv1.y ) 286 | , ( vv2.z - vv1.z, vv3.z - vv1.z ) 287 | ) 288 | 289 | ( ( s1, s2 ), ( t1, t2 ) ) = 290 | ( ( ww2.x - ww1.x, ww3.x - ww1.x ), ( ww2.y - ww1.y, ww3.y - ww1.y ) ) 291 | 292 | denom = 293 | s1 * t2 - s2 * t1 294 | 295 | r = 296 | if abs denom <= 0.000001 then 297 | 0.1 298 | 299 | else 300 | 1 / denom 301 | 302 | sdir = 303 | vec3 ((t2 * x1 - t1 * x2) * r) ((t2 * y1 - t1 * y2) * r) ((t2 * z1 - t1 * z2) * r) 304 | 305 | tdir = 306 | vec3 ((s1 * x2 - s2 * x1) * r) ((s1 * y2 - s2 * y1) * r) ((s1 * z2 - s2 * z1) * r) 307 | in 308 | ( sdir, tdir ) 309 | 310 | _ -> 311 | -- TODO: lift this error into a Result type 312 | ( vec3 -999 -999 -999, vec3 -999 -999 -999 ) 313 | 314 | 315 | getOrInsertVTN index ({ vs, vts, vns, knownVertexTextures, currentIndex } as state) = 316 | case Dict.get index knownVertexTextures of 317 | Just i -> 318 | ( state, [], i ) 319 | 320 | Nothing -> 321 | case get3 index vs vts vns of 322 | Just ( p, t, n ) -> 323 | ( { state 324 | | knownVertexTextures = Dict.insert index currentIndex knownVertexTextures 325 | , currentIndex = currentIndex + 1 326 | } 327 | , [ VertexWithTexture p t n ] 328 | , currentIndex 329 | ) 330 | 331 | Nothing -> 332 | -- TODO: lift this error into a Result type 333 | ( state, [], -999 ) 334 | 335 | 336 | getOrInsertVTNT ( s_dir, t_dir ) index ({ vs, vts, vns, knownVertexTexturesTangents, currentIndex } as state) = 337 | case Dict.get index knownVertexTexturesTangents of 338 | Just i -> 339 | case state.currentMesh of 340 | Just (WithTextureAndTangentT m) -> 341 | ( { state 342 | | currentMesh = 343 | Just 344 | (WithTextureAndTangentT 345 | { m 346 | | vertices = 347 | updateArray i 348 | (\({ sdir, tdir } as v) -> 349 | { v | sdir = V3.add sdir s_dir, tdir = V3.add tdir t_dir } 350 | ) 351 | m.vertices 352 | } 353 | ) 354 | } 355 | , Array.empty 356 | , i 357 | ) 358 | 359 | _ -> 360 | -- should never happen 361 | ( state, Array.empty, i ) 362 | 363 | Nothing -> 364 | case get3 index vs vts vns of 365 | Just ( p, t, n ) -> 366 | ( { state 367 | | knownVertexTexturesTangents = Dict.insert index currentIndex knownVertexTexturesTangents 368 | , currentIndex = currentIndex + 1 369 | } 370 | , Array.fromList [ VertexWithTextureAndTangentT p t n s_dir t_dir ] 371 | , currentIndex 372 | ) 373 | 374 | Nothing -> 375 | -- TODO: lift this error into a Result type 376 | ( state, Array.empty, -999 ) 377 | 378 | 379 | getOrInsertVN index ({ vs, vns, knownVertex, currentIndex } as state) = 380 | case Dict.get index knownVertex of 381 | Just i -> 382 | ( state, [], i ) 383 | 384 | Nothing -> 385 | case get2 index vs vns of 386 | Just ( p, n ) -> 387 | ( { state 388 | | knownVertex = Dict.insert index currentIndex knownVertex 389 | , currentIndex = currentIndex + 1 390 | } 391 | , [ Vertex p n ] 392 | , currentIndex 393 | ) 394 | 395 | Nothing -> 396 | -- TODO: lift this error into a Result type 397 | ( state, [], -999 ) 398 | 399 | 400 | fst2 ( a, b, c ) = 401 | ( a, b ) 402 | 403 | 404 | arrayUpdate i f a = 405 | case Array.get i a of 406 | Just e -> 407 | Array.set i (f e) a 408 | 409 | _ -> 410 | a 411 | 412 | 413 | triangulate threeOrFour = 414 | case threeOrFour of 415 | Three { a, b, c } -> 416 | [ ( a, b, c ) ] 417 | 418 | Four { a, b, c, d } -> 419 | [ ( a, b, c ), ( d, a, c ) ] 420 | 421 | 422 | createMesh withTangents f = 423 | let 424 | emptyMeshT = 425 | { vertices = Array.empty, indices = [] } 426 | 427 | emptyMesh = 428 | { vertices = [], indices = [] } 429 | in 430 | case f of 431 | FTVertexTextureNormal _ -> 432 | if withTangents then 433 | WithTextureAndTangentT emptyMeshT 434 | 435 | else 436 | WithTextureT emptyMesh 437 | 438 | FTVertexNormal _ -> 439 | WithoutTextureT emptyMesh 440 | 441 | 442 | 443 | -- 444 | -- Some helpers: 445 | -- 446 | 447 | 448 | t3map f ( a, b, c ) = 449 | ( f a, f b, f c ) 450 | 451 | 452 | updateArray i f a = 453 | case Array.get i a of 454 | Just v -> 455 | Array.set i (f v) a 456 | 457 | Nothing -> 458 | a 459 | 460 | 461 | get3 ( a, b, c ) a1 a2 a3 = 462 | case ( Array.get (a - 1) a1, Array.get (b - 1) a2, Array.get (c - 1) a3 ) of 463 | ( Just a_, Just b_, Just c_ ) -> 464 | Just ( a_, b_, c_ ) 465 | 466 | _ -> 467 | Nothing 468 | 469 | 470 | get2 ( a, b ) a1 a2 = 471 | case ( Array.get (a - 1) a1, Array.get (b - 1) a2 ) of 472 | ( Just a_, Just b_ ) -> 473 | Just ( a_, b_ ) 474 | 475 | _ -> 476 | Nothing 477 | -------------------------------------------------------------------------------- /src/OBJ/InternalTypes.elm: -------------------------------------------------------------------------------- 1 | module OBJ.InternalTypes exposing (Face(..), FaceTriangle(..), Group(..), Int2, Int3, Line(..), MeshT(..), MeshWithT, ThreeOrFour(..), VertexWithTextureAndTangentT) 2 | 3 | import Array exposing (Array) 4 | import Math.Vector2 exposing (Vec2) 5 | import Math.Vector3 exposing (Vec3) 6 | import OBJ.Types exposing (..) 7 | 8 | 9 | type MeshT 10 | = WithoutTextureT (MeshWith Vertex) 11 | | WithTextureT (MeshWith VertexWithTexture) 12 | | WithTextureAndTangentT (MeshWithT VertexWithTextureAndTangentT) 13 | 14 | 15 | type alias MeshWithT a = 16 | { vertices : Array a 17 | , indices : List Int3 18 | } 19 | 20 | 21 | type alias VertexWithTextureAndTangentT = 22 | { position : Vec3, texCoord : Vec2, normal : Vec3, sdir : Vec3, tdir : Vec3 } 23 | 24 | 25 | type 26 | Line 27 | -- v 1 3 4 28 | = V Vec3 29 | -- vt 2 4 30 | | Vt Vec2 31 | -- vn 3 3 1 32 | | Vn Vec3 33 | -- f 1 2 4 34 | -- f 1/3 2/3 1/7 35 | -- f 1/2/3 7/4/2 8/12/90 36 | -- f 4//8 4//1 6//2 37 | | F Face 38 | -- steteful stuff 39 | | Object String 40 | | Group String 41 | | Smooth String 42 | | MtlLib String 43 | | UseMtl String 44 | 45 | 46 | type Face 47 | = FVertexTextureNormal (ThreeOrFour Int3) 48 | | FVertexNormal (ThreeOrFour Int2) 49 | 50 | 51 | type FaceTriangle 52 | = FTVertexTextureNormal ( Int3, Int3, Int3 ) 53 | | FTVertexNormal ( Int2, Int2, Int2 ) 54 | 55 | 56 | type ThreeOrFour t 57 | = Three { a : t, b : t, c : t } 58 | | Four 59 | { a : t 60 | , b : t 61 | , c : t 62 | , d : t 63 | } 64 | 65 | 66 | type Group 67 | = GV { faces : List Int3 } 68 | | GVT { faces : List ( Int2, Int2, Int2 ) } 69 | | GVTN { faces : List ( Int3, Int3, Int3 ) } 70 | | GVN { faces : List ( Int2, Int2, Int2 ) } 71 | 72 | 73 | type alias Int2 = 74 | ( Int, Int ) 75 | 76 | 77 | type alias Int3 = 78 | ( Int, Int, Int ) 79 | -------------------------------------------------------------------------------- /src/OBJ/Parser.elm: -------------------------------------------------------------------------------- 1 | module OBJ.Parser exposing (betterFloat, canSkip, comment, fVertex, fVertexNormal, fVertexTexture, fVertexTextureNormal, face, file, formatError, fourValues, group, ignoreZ, ignoredLines, int__int, int_int, int_int_int, line, mtllib, objectName, parse, parseLine, parseLineAcc, smooth, spaces, threeOrFourValues, threeValues, toInt, usemtl, vector2, vector3, vertex, vertexNormal, vertexTexture) 2 | 3 | import Combine exposing (..) 4 | import Combine.Char exposing (..) 5 | import Combine.Num exposing (..) 6 | import Json.Decode as JD 7 | import Math.Vector2 exposing (Vec2, vec2) 8 | import Math.Vector3 as V3 exposing (Vec3, toRecord, vec3) 9 | import OBJ.InternalTypes exposing (..) 10 | import Regex 11 | 12 | 13 | 14 | -- TODO: figure out how nice error messages work 15 | -- 16 | -- The obj specs: 17 | -- http://www.martinreddy.net/gfx/3d/OBJ.spec 18 | 19 | 20 | parse : String -> Result String (List Line) 21 | parse input = 22 | String.split "\n" input 23 | |> List.foldr parseLineAcc (Ok []) 24 | 25 | 26 | parseLineAcc : String -> Result String (List Line) -> Result String (List Line) 27 | parseLineAcc line_ acc = 28 | case acc of 29 | Ok lines -> 30 | if canSkip line_ then 31 | Ok lines 32 | 33 | else 34 | parseLine line_ 35 | |> Result.andThen 36 | (\l -> 37 | Ok (l :: lines) 38 | ) 39 | 40 | Err e -> 41 | Err e 42 | 43 | 44 | canSkip : String -> Bool 45 | canSkip = 46 | regexMatches "^((\\s*)|(\\s*#.*\\r?))$" 47 | 48 | 49 | regexMatches : String -> String -> Bool 50 | regexMatches regexStr str = 51 | Regex.fromString regexStr 52 | |> Maybe.map (\regex -> Regex.contains regex str) 53 | |> Maybe.withDefault False 54 | 55 | 56 | parseLine l = 57 | case Combine.parse line l of 58 | Ok ( _, stream, result ) -> 59 | Ok result 60 | 61 | Err ( _, stream, errors ) -> 62 | Err (formatError errors stream) 63 | 64 | 65 | file : Parser s (List Line) 66 | file = 67 | ignore (many ignoredLines) (sepBy (many1 ignoredLines) line) 68 | |> ignore (many ignoredLines) 69 | |> ignore end 70 | 71 | 72 | ignoredLines : Parser s () 73 | ignoredLines = 74 | or (skip eol) (skip comment) 75 | 76 | 77 | objectName : Parser s String 78 | objectName = 79 | regex "o[ \t]+" |> keep (regex ".+") 80 | 81 | 82 | mtllib : Parser s String 83 | mtllib = 84 | regex "mtllib[ \t]+" |> keep (regex ".+") 85 | 86 | 87 | group : Parser s String 88 | group = 89 | or (regex "g[ \t]+" |> keep (regex ".+")) 90 | (char 'g' |> keep (succeed "")) 91 | 92 | 93 | smooth : Parser s String 94 | smooth = 95 | regex "s[ \t]+" |> keep (regex ".+") 96 | 97 | 98 | usemtl : Parser s String 99 | usemtl = 100 | regex "usemtl[ \t]+" |> keep (regex ".+") 101 | 102 | 103 | line : Parser s Line 104 | line = 105 | keep 106 | (choice 107 | [ map V vertex 108 | , map Vt vertexTexture 109 | , map Vn vertexNormal 110 | , map F face 111 | , map Object objectName 112 | , map Group group 113 | , map Smooth smooth 114 | , map UseMtl usemtl 115 | , map MtlLib mtllib 116 | ] 117 | ) 118 | (regex "[ \t]*") 119 | 120 | 121 | face : Parser s Face 122 | face = 123 | regex "f[ \t]+" 124 | |> keep 125 | (choice 126 | [ fVertexTextureNormal 127 | , fVertexNormal 128 | , fVertex 129 | , fVertexTexture 130 | ] 131 | ) 132 | 133 | 134 | fVertex : Parser s a 135 | fVertex = 136 | keep (fail "Models with no precalculated vertex normals are not supported!") (threeOrFourValues int) 137 | 138 | 139 | fVertexTexture : Parser s a 140 | fVertexTexture = 141 | keep (fail "Models with no precalculated vertex normals are not supported!") (threeOrFourValues int_int) 142 | 143 | 144 | fVertexTextureNormal : Parser s Face 145 | fVertexTextureNormal = 146 | map FVertexTextureNormal <| threeOrFourValues int_int_int 147 | 148 | 149 | fVertexNormal : Parser s Face 150 | fVertexNormal = 151 | map FVertexNormal <| threeOrFourValues int__int 152 | 153 | 154 | threeValues : (a -> a -> a -> b) -> Parser s a -> Parser s b 155 | threeValues tagger parser = 156 | parser 157 | |> map tagger 158 | |> andMap (spaces |> keep parser) 159 | |> andMap (spaces |> keep parser) 160 | 161 | 162 | fourValues : (a -> a -> a -> a -> b) -> Parser s a -> Parser s b 163 | fourValues tagger parser = 164 | parser 165 | |> map tagger 166 | |> andMap (spaces |> keep parser) 167 | |> andMap (spaces |> keep parser) 168 | |> andMap (spaces |> keep parser) 169 | 170 | 171 | threeOrFourValues : Parser s a -> Parser s (ThreeOrFour a) 172 | threeOrFourValues elementType = 173 | or (map Four <| fourValues (\a b c d -> { a = a, b = b, c = c, d = d }) elementType) 174 | (map Three <| threeValues (\a b c -> { a = a, b = b, c = c }) elementType) 175 | 176 | 177 | int_int : Parser s ( Int, Int ) 178 | int_int = 179 | int 180 | |> map tuple2 181 | |> andMap (string "/" |> keep int) 182 | 183 | 184 | int_int_int : Parser s ( Int, Int, Int ) 185 | int_int_int = 186 | int 187 | |> map tuple3 188 | |> andMap (string "/" |> keep int) 189 | |> andMap (string "/" |> keep int) 190 | 191 | 192 | tuple2 : a -> b -> ( a, b ) 193 | tuple2 a b = 194 | ( a, b ) 195 | 196 | 197 | tuple3 : a -> b -> c -> ( a, b, c ) 198 | tuple3 a b c = 199 | ( a, b, c ) 200 | 201 | 202 | int__int : Parser s ( Int, Int ) 203 | int__int = 204 | int 205 | |> map tuple2 206 | |> andMap (string "//" |> keep int) 207 | 208 | 209 | vertexNormal : Parser s Vec3 210 | vertexNormal = 211 | regex "vn[ \t]+" |> keep (map V3.normalize vector3) 212 | 213 | 214 | vertexTexture : Parser s Vec2 215 | vertexTexture = 216 | regex "vt[ \t]+" |> keep (or (map ignoreZ vector3) vector2) 217 | 218 | 219 | vertex : Parser s Vec3 220 | vertex = 221 | regex "v[ \t]+" |> keep vector3 222 | 223 | 224 | comment : Parser s String 225 | comment = 226 | regex "#" |> keep (regex ".*") 227 | 228 | 229 | vector3 : Parser s Vec3 230 | vector3 = 231 | threeValues vec3 betterFloat 232 | 233 | 234 | spaces : Parser s String 235 | spaces = 236 | regex "[ \t]+" 237 | 238 | 239 | vector2 : Parser s Vec2 240 | vector2 = 241 | betterFloat |> map vec2 |> andMap (spaces |> keep betterFloat) 242 | 243 | 244 | betterFloat : Parser s Float 245 | betterFloat = 246 | map parseFloatOrZero <| regex "[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?" 247 | 248 | 249 | parseFloatOrZero s = 250 | Result.withDefault 0 (JD.decodeString JD.float s) 251 | 252 | 253 | formatError : List String -> InputStream -> String 254 | formatError ms stream = 255 | let 256 | location = 257 | currentLocation stream 258 | 259 | separator = 260 | "| " 261 | 262 | expectationSeparator = 263 | "\n * " 264 | 265 | lineNumberOffset = 266 | floor (logBase 10 (toFloat location.line)) + 1 267 | 268 | separatorOffset = 269 | String.length separator 270 | 271 | padding = 272 | location.column + separatorOffset + 2 273 | in 274 | "Parse error around line:\n\n" 275 | ++ String.fromInt location.line 276 | ++ separator 277 | ++ location.source 278 | ++ "\n" 279 | ++ String.padLeft padding ' ' "^" 280 | ++ "\nI expected one of the following:\n" 281 | ++ expectationSeparator 282 | ++ String.join expectationSeparator ms 283 | 284 | 285 | toInt : String -> Int 286 | toInt s = 287 | Maybe.withDefault 0 <| String.toInt s 288 | 289 | 290 | ignoreZ : Vec3 -> Vec2 291 | ignoreZ v = 292 | let 293 | { x, y, z } = 294 | toRecord v 295 | in 296 | vec2 x y 297 | -------------------------------------------------------------------------------- /src/OBJ/Types.elm: -------------------------------------------------------------------------------- 1 | module OBJ.Types exposing 2 | ( ObjFile, Mesh(..), MeshWith 3 | , Vertex, VertexWithTexture, VertexWithTextureAndTangent 4 | ) 5 | 6 | {-| These are the types used by the obj loader. 7 | 8 | @docs ObjFile, Mesh, MeshWith 9 | 10 | -- 11 | 12 | @docs Vertex, VertexWithTexture, VertexWithTextureAndTangent 13 | 14 | -} 15 | 16 | import Dict exposing (Dict) 17 | import Math.Vector2 exposing (Vec2) 18 | import Math.Vector3 exposing (Vec3) 19 | import Math.Vector4 exposing (Vec4) 20 | 21 | 22 | {-| A .obj file is optionally divided into different groups/objects. 23 | Each group/object is optionally made up of different meshes, each with it's own material. 24 | 25 | So the keys of this dictionary are: 26 | 27 | Dict GroupNameOrObjectName (Dict MaterialName Mesh) 28 | 29 | If no name is specified in the input file, "__default__" will be used instead. 30 | 31 | -} 32 | type alias ObjFile = 33 | Dict String (Dict String Mesh) 34 | 35 | 36 | {-| A `Mesh` loaded by the obj loader is a record with a list of vertices and a list of indices. 37 | Depending on the mesh type and the loading options you get a different kind of mesh. 38 | They differ on what information a vertex contains. 39 | 40 | These meshes are meant to be used with `WebGL.indexedTriangles mesh.vertices mesh.indices`. 41 | 42 | -} 43 | type Mesh 44 | = WithoutTexture (MeshWith Vertex) 45 | | WithTexture (MeshWith VertexWithTexture) 46 | | WithTextureAndTangent (MeshWith VertexWithTextureAndTangent) 47 | 48 | 49 | {-| Defines a mesh: vertices of any type, and a list of their integer indices 50 | -} 51 | type alias MeshWith a = 52 | { vertices : List a 53 | , indices : List ( Int, Int, Int ) 54 | } 55 | 56 | 57 | {-| A 3D position with a normal 58 | -} 59 | type alias Vertex = 60 | { position : Vec3, normal : Vec3 } 61 | 62 | 63 | {-| A 3D position with a normal and a 2D texture position. 64 | -} 65 | type alias VertexWithTexture = 66 | { position : Vec3, texCoord : Vec2, normal : Vec3 } 67 | 68 | 69 | {-| The `tangent` is a vector pointing tangential to the object surface, in the direction of the `u` texture coordinate. 70 | This is needed for doing tangent space normal mapping. 71 | The 4th component is either 1 or -1 and has to be used to get the bitangent in the glsl shader, 72 | e.g: `vec3 bitangent = cross(normal, tangent.xyz) * tangent.w` 73 | 74 | more info here: 75 | 76 | 77 | -} 78 | type alias VertexWithTextureAndTangent = 79 | { position : Vec3, texCoord : Vec2, normal : Vec3, tangent : Vec4 } 80 | -------------------------------------------------------------------------------- /tests/ObjData.elm: -------------------------------------------------------------------------------- 1 | module ObjData exposing (basicShapeExpectedOutput, basicShapeWithTextureAndNormals) 2 | 3 | import Math.Vector2 exposing (vec2) 4 | import Math.Vector3 exposing (vec3) 5 | import Math.Vector4 exposing (vec4) 6 | 7 | 8 | basicShapeWithTextureAndNormals = 9 | """ 10 | v 0.459620 3.630721 0.459620 11 | v 0.650002 3.630721 0.000000 12 | v 0.000000 3.835475 0.000000 13 | v 0.000000 3.630721 0.650002 14 | 15 | vt 0.861694 0.549074 16 | vt 0.877784 0.587917 17 | vt 0.822851 0.587917 18 | vt 0.889835 0.520933 19 | vt 0.861694 0.626760 20 | vt 0.822851 0.532984 21 | 22 | vn 0.301361 0.878782 0.370032 23 | vn 0.474745 0.878783 0.048561 24 | vn 0.000000 1.000000 0.000000 25 | vn -0.048561 0.878783 0.474745 26 | vn 0.301361 0.878782 0.370032 27 | vn 0.000000 1.000000 0.000000 28 | 29 | f 1/1/1 2/2/2 3/3/3 30 | f 4/6/4 1/1/5 3/3/6 31 | """ 32 | 33 | 34 | basicShapeExpectedOutput = 35 | [ { normal = vec3 0.301361 0.878782 0.370032 36 | , position = vec3 0.45962 3.630721 0.45962 37 | , tangent = vec4 0.947002 -0.321108 -0.008663 1 38 | , texCoord = vec2 0.861694 0.549074 39 | } 40 | , { normal = vec3 0.474744 0.878782 0.04856 41 | , position = vec3 0.650002 3.630721 0 42 | , tangent = vec4 0.879998 -0.474885 -0.009335 1 43 | , texCoord = vec2 0.877784 0.587917 44 | } 45 | , { normal = vec3 0 1 0 46 | , position = vec3 0 3.835475 0 47 | , tangent = vec4 1 0 0 1 48 | , texCoord = vec2 0.822851 0.587917 49 | } 50 | , { normal = vec3 -0.04856 0.878782 0.474744 51 | , position = vec3 0 3.630721 0.650002 52 | , tangent = vec4 0.996878 0.013016 0.077875 1 53 | , texCoord = vec2 0.822851 0.532984 54 | } 55 | , { normal = vec3 0.301361 0.878782 0.370032 56 | , position = vec3 0.45962 3.630721 0.45962 57 | , tangent = vec4 0.952264 -0.297212 -0.069697 1 58 | , texCoord = vec2 0.861694 0.549074 59 | } 60 | , { normal = vec3 0 1 0 61 | , position = vec3 0 3.835475 0 62 | , tangent = vec4 0.999999 0 0.000011 1 63 | , texCoord = vec2 0.822851 0.587917 64 | } 65 | ] 66 | -------------------------------------------------------------------------------- /tests/ParserTests.elm: -------------------------------------------------------------------------------- 1 | module ParserTests exposing (suite) 2 | 3 | import Combine exposing (ParseError, ParseOk, Parser) 4 | import Combine.Num 5 | import Dict exposing (Dict) 6 | import Expect exposing (Expectation, FloatingPointTolerance(..)) 7 | import Fuzz exposing (Fuzzer, int) 8 | import Math.Vector2 as Vector2 exposing (Vec2) 9 | import Math.Vector3 as Vector3 exposing (Vec3, vec3) 10 | import Math.Vector4 as Vector4 exposing (Vec4) 11 | import OBJ exposing (parseObjStringWith) 12 | import OBJ.InternalTypes exposing (Line(..)) 13 | import OBJ.Parser exposing (fourValues, parseLine, threeValues) 14 | import OBJ.Types exposing (Mesh(..), MeshWith, ObjFile, Vertex, VertexWithTexture, VertexWithTextureAndTangent) 15 | import ObjData exposing (basicShapeExpectedOutput, basicShapeWithTextureAndNormals) 16 | import Test exposing (..) 17 | 18 | 19 | triplify : a -> a -> a -> List a 20 | triplify a b c = 21 | [ a, b, c ] 22 | 23 | 24 | quadify a b c d = 25 | [ a, b, c, d ] 26 | 27 | 28 | tripleParser : Parser s (List Int) 29 | tripleParser = 30 | threeValues triplify Combine.Num.int 31 | 32 | 33 | quadParser : Parser s (List Int) 34 | quadParser = 35 | fourValues quadify Combine.Num.int 36 | 37 | 38 | suite : Test 39 | suite = 40 | describe "OBJ Parser" 41 | [ fuzz int "can use Combine's int parser to parse a single Int" <| 42 | \number -> 43 | String.fromInt number 44 | |> Combine.parse Combine.Num.int 45 | |> expectParsedValueEquals number 46 | , test "has a `threeValues` method that can parse three Ints" <| 47 | \() -> 48 | Combine.parse tripleParser "1 -2 3" 49 | |> expectParsedValueEquals [ 1, -2, 3 ] 50 | , test "has a `fourValues` method that can parse four Ints" <| 51 | \() -> 52 | Combine.parse quadParser "1 2 -3 4" 53 | |> expectParsedValueEquals [ 1, 2, -3, 4 ] 54 | , test "has a line method that can parse a single line" <| 55 | \() -> 56 | parseLine "v 0.1 -0.2 0.3" 57 | |> equalsOrFail (V (vec3 0.1 -0.2 0.3)) 58 | , test "can parse an empty string" <| 59 | \() -> 60 | parseObjStringWith settings "# Comment\n" 61 | |> equalsOrFail Dict.empty 62 | , test "can parse vertices from a real OBJ-formatted string" <| 63 | \() -> 64 | parseObjStringWith settings basicShapeWithTextureAndNormals 65 | |> Result.andThen getMesh 66 | |> Result.andThen getVertices 67 | -- Turn our list of vertices into a list of expectations (based on expectations) 68 | |> Result.map (List.map2 vertexWithTextureAndTangentsEqual basicShapeExpectedOutput) 69 | |> Result.map (List.foldl andAlso Expect.pass) 70 | |> failErrorResults 71 | ] 72 | 73 | 74 | vertexWithTextureAndTangentsEqual : VertexWithTextureAndTangent -> VertexWithTextureAndTangent -> Expectation 75 | vertexWithTextureAndTangentsEqual expected actual = 76 | vec3Within expected.normal actual.normal 77 | |> andAlso (vec3Within expected.position actual.position) 78 | |> andAlso (vec4Within expected.tangent actual.tangent) 79 | |> andAlso (vec2Within expected.texCoord actual.texCoord) 80 | 81 | 82 | nearEnough = 83 | Expect.within (Absolute 0.0001) 84 | 85 | 86 | vec2Within : Vec2 -> Vec2 -> Expectation 87 | vec2Within expected actual = 88 | let 89 | e = 90 | Vector2.toRecord expected 91 | 92 | a = 93 | Vector2.toRecord actual 94 | in 95 | nearEnough e.x a.x 96 | |> andAlso (nearEnough e.y a.y) 97 | 98 | 99 | vec3Within : Vec3 -> Vec3 -> Expectation 100 | vec3Within expected actual = 101 | let 102 | e = 103 | Vector3.toRecord expected 104 | 105 | a = 106 | Vector3.toRecord actual 107 | in 108 | nearEnough e.x a.x 109 | |> andAlso (nearEnough e.y a.y) 110 | |> andAlso (nearEnough e.z a.z) 111 | 112 | 113 | vec4Within : Vec4 -> Vec4 -> Expectation 114 | vec4Within expected actual = 115 | let 116 | e = 117 | Vector4.toRecord expected 118 | 119 | a = 120 | Vector4.toRecord actual 121 | in 122 | nearEnough e.x a.x 123 | |> andAlso (nearEnough e.y a.y) 124 | |> andAlso (nearEnough e.z a.z) 125 | |> andAlso (nearEnough e.w a.w) 126 | 127 | 128 | 129 | -- See https://github.com/elm-community/elm-test/issues/214 130 | 131 | 132 | andAlso : Expect.Expectation -> Expect.Expectation -> Expect.Expectation 133 | andAlso l r = 134 | Expect.all [ always l, always r ] () 135 | 136 | 137 | getVertices : Mesh -> Result String (List VertexWithTextureAndTangent) 138 | getVertices mesh = 139 | case mesh of 140 | WithoutTexture _ -> 141 | Err "WithoutTexture found" 142 | 143 | WithTexture _ -> 144 | Err "WithTexture found" 145 | 146 | WithTextureAndTangent m -> 147 | Ok m.vertices 148 | 149 | 150 | getMesh : ObjFile -> Result String Mesh 151 | getMesh obj = 152 | Dict.get "__default__" obj 153 | |> Maybe.andThen (Dict.get "__default__") 154 | |> Maybe.map Ok 155 | |> Maybe.withDefault (Err "couldn't find __default__") 156 | 157 | 158 | settings = 159 | { withTangents = True } 160 | 161 | 162 | equalsOrFail : a -> Result String a -> Expectation 163 | equalsOrFail expected result = 164 | case result of 165 | Err message -> 166 | Expect.fail <| "FAILED: " ++ message 167 | 168 | Ok data -> 169 | Expect.equal data expected 170 | 171 | 172 | failErrorResults : Result String Expectation -> Expectation 173 | failErrorResults result = 174 | case result of 175 | Err message -> 176 | Expect.fail <| "FAILED: " ++ message 177 | 178 | Ok exp -> 179 | exp 180 | 181 | 182 | expectParsedValueEquals expected parseResult = 183 | parseResult 184 | |> Result.map (\( state, is, res ) -> res) 185 | |> (\result -> 186 | case result of 187 | Err ( _, _, messages ) -> 188 | Expect.fail <| "FAILED: " ++ String.join "\n" messages 189 | 190 | Ok data -> 191 | Expect.equal data expected 192 | ) 193 | --------------------------------------------------------------------------------