From 3b274110c8b696de7b65f76faf550af2d0b76dac Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 14 Jul 2024 13:37:00 +0200 Subject: [PATCH 01/22] track materials --- src/io/obj.jl | 94 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 4 deletions(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index 5f48873..4edc4e0 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -7,10 +7,25 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, pointtype=Point3f, normaltype=Vec3f, uvtype=Any) + # function parse_bool(x, default) + # if lowercase(x) == "off" || x == "0" + # return false + # elseif lowercase(x) == "on" || x == "1" + # return true + # else + # error("Failed to parse $x as Bool.") + # end + # end + points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], facetype[] - f_uv_n_faces = (faces, facetype[], facetype[]) - last_command = "" - attrib_type = nothing + f_uv_n_faces = (faces, facetype[], facetype[], facetype[]) + + # TODO: Allow GeometryBasics to keep track of this in Mesh? + material_ids = Int[] + materials = Dict{String, Int}() + current_material = 0 + material_counter = 0 + for full_line in eachline(stream(io)) # read a line, remove newline and leading/trailing whitespaces line = strip(chomp(full_line)) @@ -22,8 +37,10 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, if "v" == command # mesh always has vertices push!(points, pointtype(parse.(eltype(pointtype), lines))) + elseif "vn" == command push!(v_normals, normaltype(parse.(eltype(normaltype), lines))) + elseif "vt" == command if length(lines) == 2 if uvtype == Any @@ -40,7 +57,10 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, else error("Unknown UVW coordinate: $lines") end + elseif "f" == command # mesh always has faces + # add material + if any(x-> occursin("//", x), lines) fs = process_face_normal(lines) elseif any(x-> occursin("/", x), lines) @@ -52,11 +72,70 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, for i = 1:length(first(fs)) append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i))) end + + # elseif "s" == command # Blender sets this just before faces + # shading = parse_bool(lines[1]) + + # elseif "o" == command # Blender sets this before vertices + # object_name = join(lines, ' ') + + # elseif "g" == command + # group_name = join(lines, ' ') + + # elseif "mtllib" == command + # filename = join(lines, ' ') + + elseif "usemtl" == command # Blender sets this just before faces + name = join(lines, ' ') + last_material = current_material + current_material = get!(materials, name) do + material_counter += 1 + end + if current_material != last_material + push!(material_ids, current_material) + last_material == 0 && continue # first material + + # find material face buffer and push all the material faces + target_N = length(faces) + face = facetype(last_material) + for i in 2:4 + if length(f_uv_n_faces[i]) < target_N + sizehint!(f_uv_n_faces[i], target_N) + while length(f_uv_n_faces[i]) < target_N + push!(f_uv_n_faces[i], face) + end + break + end + end + end else #TODO end end end + + # drop material ids if no materials were specified + if material_counter == 1 + for i in 4:-1:1 + if !isempty(f_uv_n_faces[i]) + empty!(f_uv_n_faces[i]) + break + end + end + empty!(material_ids) + else + face = facetype(current_material) + target_N = length(faces) + for i in 2:4 + if length(f_uv_n_faces[i]) < target_N + sizehint!(f_uv_n_faces[i], target_N) + while length(f_uv_n_faces[i]) < target_N + push!(f_uv_n_faces[i], face) + end + break + end + end + end point_attributes = Dict{Symbol, Any}() non_empty_faces = filtertuple(!isempty, f_uv_n_faces) @@ -78,6 +157,10 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, end if !isempty(v_normals) point_attributes[:normals] = v_normals[attrib_maps[counter]] + counter += 1 + end + if !isempty(material_ids) + point_attributes[:material] = material_ids[attrib_maps[counter]] end else # we have vertex indexing - no need to remap @@ -88,7 +171,10 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, if !isempty(uv) point_attributes[:uv] = uv end - + if !isempty(material_ids) + point_attributes[:material] = material_ids + end + end return Mesh(meta(points; point_attributes...), faces) From 5cbd96559df3953d4bd32359a20e0ae66698aac0 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 14 Jul 2024 13:37:28 +0200 Subject: [PATCH 02/22] add experimental mtl loading + mesh splitting util --- src/io/obj.jl | 284 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 283 insertions(+), 1 deletion(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index 4edc4e0..a1bf1ab 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -72,7 +72,7 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, for i = 1:length(first(fs)) append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i))) end - + # elseif "s" == command # Blender sets this just before faces # shading = parse_bool(lines[1]) @@ -219,3 +219,285 @@ function save(f::Stream{format"OBJ"}, mesh::AbstractMesh) println(io, "f ", join(convert.(Int, f), " ")) end end + + +# Experimental stuff for loading .mtl files and working with multiple materials + +""" + MehsIO.split_mesh(mesh) + +Experimental function for splitting a mesh based material indices. +Also remaps vertices to avoid passing all vertices with a submesh. +""" +function split_mesh(mesh) + ps = coordinates(mesh) + ns = normals(mesh) + uvs = texturecoordinates(mesh) + ids = mesh.material + fs = faces(mesh) + + meshes = Dict{Int, Any}() + target_ids = unique(ids) + IndexType = eltype(eltype(fs)) + + for target_id in target_ids + _fs = eltype(fs)[] + indexmap = Dict{UInt32, UInt32}() + counter = MeshIO._typemin(IndexType) + + for f in fs + if any(ids[f] .== target_id) + f = map(f) do _i + i = GeometryBasics.value(_i) + if haskey(indexmap, i) + return indexmap[i] + else + indexmap[i] = counter + counter += 1 + return counter-1 + end + end + push!(_fs, f) + end + end + + indices = Vector{UInt32}(undef, counter-1) + for (old, new) in indexmap + indices[new] = old + end + + meshes[target_id] = GeometryBasics.Mesh( + meta(ps[indices], normals = ns[indices], uv = uvs[indices]), _fs + ) + end + + return meshes +end + +""" + load_materials(obj_filename) + +Experimental functionality for loading am mtl file attached to an obj file. Also +recovers loads the object_group_id -> (object, group) name mapping from the obj +file. +""" +function load_materials(filename::String) + endswith(filename, ".obj") || error("File should be a .obj file!") + + data = Dict{String, Any}() + mat2id = Dict{String, Int}() + current_material = 0 + material_counter = 0 + + path = joinpath(splitpath(filename)[1:end-1]) + file = open(filename, "r") + + for full_line in eachline(file) + # read a line, remove newline and leading/trailing whitespaces + line = strip(chomp(full_line)) + !isascii(line) && error("non valid ascii in obj") + + if !startswith(line, "#") && !isempty(line) && !all(iscntrl, line) #ignore comments + lines = split(line) + command = popfirst!(lines) #first is the command, rest the data + + if "usemtl" == command + name = join(lines, ' ') + current_material = get!(mat2id, name) do + material_counter += 1 + end + + elseif "mtllib" == command + filename = join(lines, ' ') + materials = _load_mtl(joinpath(path, filename)) + for (k, v) in materials + data[k] = v + end + else + # Skipped + end + end + end + + close(file) + + data["id to material"] = Dict([v => k for (k, v) in mat2id]) + + return data +end + +function _load_mtl(filename::String) + endswith(filename, ".mtl") || error("File should be a .mtl file!") + materials = Dict{String, Dict{String, Any}}() + material = Dict{String, Any}() + + name_lookup = Dict( + "Ka" => "ambient", "Kd" => "diffuse", "Ks" => "specular", + "Ns" => "shininess", "d" => "alpha", "Tr" => "transmission", # 1 - alpha + "Ni" => "refractive index", "illum" => "illumination model", + # PBR + "Pr" => "roughness", "Pm" => "metallic", "Ps" => "sheen", + "Pc" => "clearcoat thickness", "Pcr" => "clearcoat roughness", + "Ke" => "emissive", "aniso" => "anisotropy", + "anisor" => "anisotropy rotation", + # texture maps + "map_Ka" => "ambient map", "map_Kd" => "diffuse map", + "map_Ks" => "specular map", "map_Ns" => "shininess map", + "map_d" => "alpha map", "map_Tr" => "transmission map", + "map_bump" => "bump map", "bump" => "bump map", + "disp" => "displacement map", "decal" => "decal map", + "refl" => "reflection map", "norm" => "normal map", + "map_Pr" => "roughness map", "map_Pm" => "metallic map", + "map_Ps" => "sheen map", "map_Ke" => "emissive map", + "map_RMA" => "roughness metalness occlusion map", + "map_ORM" => "occlusion roughness metalness map" + ) + + path = joinpath(splitpath(filename)[1:end-1]) + file = open(filename, "r") + + try + for full_line in eachline(file) + # read a line, remove newline and leading/trailing whitespaces + line = strip(chomp(full_line)) + !isascii(line) && error("non valid ascii in obj") + + if !startswith(line, "#") && !isempty(line) && !all(iscntrl, line) #ignore comments + lines = split(line) + command = popfirst!(lines) #first is the command, rest the data + + if command == "newmtl" + name = join(lines, ' ') + materials[name] = material = Dict{String, Any}() + + elseif command == "Ka" || command == "Kd" || command == "Ks" + material[name_lookup[command]] = Vec3f(parse.(Float32, lines)...) + + elseif command == "Ns" || command == "Ni" || command == "Pr" || + command == "Pm" || command == "Ps" || command == "Pc" || + command == "Pcr" || command == "Ke" || command == "aniso" || + command == "anisor" + + material[name_lookup[command]] = parse.(Float32, lines[1]) + + elseif command == "d" + haskey(material, "alpha") && error("Material alpha doubly defined.") + material[name_lookup[command]] = parse.(Float32, lines[1]) + + elseif command == "Tr" + haskey(material, "alpha") && error("Material alpha doubly defined.") + material[name_lookup["d"]] = 1f0 - parse.(Float32, lines[1]) + + # elseif Tf # transmission filter + + elseif command == "illum" + # See https://en.wikipedia.org/wiki/Wavefront_.obj_file#Basic_materials + material[name_lookup[command]] = parse.(Int, lines[1]) + + elseif startswith(command, "map") || command == "bump" || command == "norm" || + command == "refl" || command == "disp" || command == "decal" + + # TODO: treat all the texture options + material[get(name_lookup, command, command)] = parse_texture_info(path, lines) + + else + material[command] = lines + end + end + end + + finally + close(file) + end + + return materials +end + +function parse_texture_info(parent_path::String, lines::Vector{SubString{String}}) + idx = 1 + output = Dict{String, Any}() + name_lookup = Dict( + "o" => "origin offset", "s" => "scale", "t" => "turbulence", + "blendu" => "blend horizontal", "blendv" => "blend vertical", + "boost" => "mipmap sharpness", "bm" => "bump multiplier" + ) + + function parse_bool(x, default) + if lowercase(x) == "off" || x == "0" + return false + elseif lowercase(x) == "on" || x == "1" + return true + else + error("Failed to parse $x as Bool.") + end + end + + while idx < length(lines) + 1 + if startswith(lines[idx], '-') + command = lines[idx][2:end] + + if command == "blendu" || command == "blendv" + name = name_lookup[command] + output[name] = parse_bool(lines[idx+1], true) + idx += 2 + + elseif command == "boost" || command == "bm" + output[name_lookup[command]] = parse(Float32, lines[idx+1]) + idx += 2 + + elseif command == "mm" + output["brightness"] = parse(Float32, lines[idx+1]) + output["contrast"] = parse(Float32, lines[idx+2]) + idx += 3 + + elseif command == "o" || command == "s" || command == "t" + default = command == "s" ? 1f0 : 0f0 + x = parse(Float32, lines[idx+1]) + y = length(lines) >= idx+2 ? tryparse(Float32, lines[idx+2]) : nothing + z = length(lines) >= idx+3 ? tryparse(Float32, lines[idx+3]) : nothing + output[name_lookup[command]] = Vec3f( + x, something(y, default), something(z, default) + ) + idx += 2 + (y !== nothing) + (z !== nothing) + + elseif command == "texres" # is this only one value? + output["resolution"] = parse(Float32, lines[idx+1]) + idx += 2 + + elseif command == "clamp" + output["clamp"] = parse_bool(lines[idx+1]) + idx += 2 + + elseif command == "imfchan" + output["channel"] = lines[idx+1] + idx += 2 + + elseif command == "type" + output[command] = lines[idx+1] + idx += 2 + + # TODO: PBR tags + + else + @warn "Failed to parse -$command" + idx += 1 + end + else + filepath = joinpath(parent_path, lines[idx]) + i = idx+1 + while i <= length(lines) && !startswith(lines[i], '-') + filepath = filepath * ' ' * lines[i] + i += 1 + end + @info filepath + if isfile(filepath) + output["filename"] = filepath + idx = i + else + idx += 1 + end + end + end + + return output +end \ No newline at end of file From 2df6da85766298f12e3ee97866f39691b4a97288 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 14 Jul 2024 14:12:16 +0200 Subject: [PATCH 03/22] fix test failures --- src/io/obj.jl | 53 ++++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index a1bf1ab..cb5b8c7 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -18,7 +18,9 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, # end points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], facetype[] - f_uv_n_faces = (faces, facetype[], facetype[], facetype[]) + material_faces = facetype[] + f_uv_n_faces = (faces, facetype[], facetype[], material_faces) + # TODO: Allow GeometryBasics to keep track of this in Mesh? material_ids = Int[] @@ -98,14 +100,9 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, # find material face buffer and push all the material faces target_N = length(faces) face = facetype(last_material) - for i in 2:4 - if length(f_uv_n_faces[i]) < target_N - sizehint!(f_uv_n_faces[i], target_N) - while length(f_uv_n_faces[i]) < target_N - push!(f_uv_n_faces[i], face) - end - break - end + sizehint!(material_faces, target_N) + while length(material_faces) < target_N + push!(material_faces, face) end end else @@ -115,25 +112,14 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, end # drop material ids if no materials were specified - if material_counter == 1 - for i in 4:-1:1 - if !isempty(f_uv_n_faces[i]) - empty!(f_uv_n_faces[i]) - break - end - end + if material_counter == 0 empty!(material_ids) else face = facetype(current_material) target_N = length(faces) - for i in 2:4 - if length(f_uv_n_faces[i]) < target_N - sizehint!(f_uv_n_faces[i], target_N) - while length(f_uv_n_faces[i]) < target_N - push!(f_uv_n_faces[i], face) - end - break - end + sizehint!(material_faces, target_N) + while length(material_faces) < target_N + push!(material_faces, face) end end @@ -151,13 +137,24 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, # Update order of vertex attributes points = points[attrib_maps[1]] counter = 2 + # With materials we can have merged position-uv-normal faces + # but still end up in this branch because of the material index, so + # we need to check if the uv/normals faces are set before remapping if !isempty(uv) - point_attributes[:uv] = uv[attrib_maps[counter]] - counter += 1 + if !isempty(f_uv_n_faces[counter]) + point_attributes[:uv] = uv[attrib_maps[counter]] + counter += 1 + else + point_attributes[:uv] = uv[attrib_maps[counter-1]] + end end if !isempty(v_normals) - point_attributes[:normals] = v_normals[attrib_maps[counter]] - counter += 1 + if !isempty(f_uv_n_faces[counter]) + point_attributes[:normals] = v_normals[attrib_maps[counter]] + counter += 1 + else + point_attributes[:normals] = v_normals[attrib_maps[counter-1]] + end end if !isempty(material_ids) point_attributes[:material] = material_ids[attrib_maps[counter]] From fd36a88a7ef18c7ab242a4b0f08d601546282533 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 14 Jul 2024 16:49:09 +0200 Subject: [PATCH 04/22] normalize path syntax and allow broken paths --- src/io/obj.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index cb5b8c7..16c2884 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -486,8 +486,9 @@ function parse_texture_info(parent_path::String, lines::Vector{SubString{String} filepath = filepath * ' ' * lines[i] i += 1 end - @info filepath - if isfile(filepath) + filepath = replace(filepath, "\\\\" => "/") + filepath = replace(filepath, "\\" => "/") + if isfile(filepath) || endswith(lowercase(filepath), r"\.(png|jpg|jpeg|tiff|bmp)") output["filename"] = filepath idx = i else From ba3b3487bf364e03f6f8cfbc5e05e0bdb8f1d6ee Mon Sep 17 00:00:00 2001 From: ffreyer Date: Wed, 4 Sep 2024 23:04:05 +0200 Subject: [PATCH 05/22] make cat loadable --- src/MeshIO.jl | 2 -- src/io/obj.jl | 63 +++++++++++++++++++++------------------------------ src/util.jl | 56 --------------------------------------------- 3 files changed, 26 insertions(+), 95 deletions(-) delete mode 100644 src/util.jl diff --git a/src/MeshIO.jl b/src/MeshIO.jl index 0f50e29..01d0c24 100644 --- a/src/MeshIO.jl +++ b/src/MeshIO.jl @@ -9,8 +9,6 @@ using FileIO: FileIO, @format_str, Stream, File, stream, skipmagic import Base.show -include("util.jl") - include("io/off.jl") include("io/ply.jl") include("io/stl.jl") diff --git a/src/io/obj.jl b/src/io/obj.jl index 5f48873..4101bf3 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -5,10 +5,9 @@ ############################## function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, - pointtype=Point3f, normaltype=Vec3f, uvtype=Any) + pointtype=Point3f, normaltype=Vec3f, uvtype=Vec2f) - points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], facetype[] - f_uv_n_faces = (faces, facetype[], facetype[]) + points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], Any[] last_command = "" attrib_type = nothing for full_line in eachline(stream(io)) @@ -43,14 +42,22 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, elseif "f" == command # mesh always has faces if any(x-> occursin("//", x), lines) fs = process_face_normal(lines) + pos_faces = triangulated_faces(facetype, getindex.(fs, 1)) + normal_faces = triangulated_faces(facetype, getindex.(fs, 2)) + append!(faces, GeometryBasics.NormalFace.(pos_faces, normal_faces)) + elseif any(x-> occursin("/", x), lines) fs = process_face_uv_or_normal(lines) + pos_faces = triangulated_faces(facetype, getindex.(fs, 1)) + uv_faces = triangulated_faces(facetype, getindex.(fs, 2)) + if length(fs[1]) == 2 + append!(faces, GeometryBasics.UVFace.(pos_faces, uv_faces)) + else + normal_faces = triangulated_faces(facetype, getindex.(fs, 3)) + append!(faces, GeometryBasics.NormalUVFace.(pos_faces, normal_faces, uv_faces)) + end else append!(faces, triangulated_faces(facetype, lines)) - continue - end - for i = 1:length(first(fs)) - append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i))) end else #TODO @@ -58,40 +65,22 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, end end - point_attributes = Dict{Symbol, Any}() - non_empty_faces = filtertuple(!isempty, f_uv_n_faces) - - # Do we have faces with different indices for positions and normals - # (and texture coordinates) per vertex? - if length(non_empty_faces) > 1 - - # map vertices with distinct indices for possition and normal (and uv) - # to new indices, updating faces along the way - faces, attrib_maps = merge_vertex_attribute_indices(non_empty_faces) - - # Update order of vertex attributes - points = points[attrib_maps[1]] - counter = 2 - if !isempty(uv) - point_attributes[:uv] = uv[attrib_maps[counter]] - counter += 1 - end - if !isempty(v_normals) - point_attributes[:normals] = v_normals[attrib_maps[counter]] - end + vertex_attributes = Dict{Symbol, Any}() - else # we have vertex indexing - no need to remap + # TODO: add GeometryBasics convenience for dropping nothing vertex attributes? + if !isempty(v_normals) + vertex_attributes[:normal] = v_normals + end - if !isempty(v_normals) - point_attributes[:normals] = v_normals - end - if !isempty(uv) - point_attributes[:uv] = uv - end - + if !isempty(uv) + vertex_attributes[:uv] = uv end - return Mesh(meta(points; point_attributes...), faces) + # TODO: Can we avoid this conversion? + # Also, is it safe to do? Or can an obj file define different face types for different groups? + faces = convert(Vector{typeof(first(faces))}, faces) + + return GeometryBasics.mesh(points, faces, facetype = facetype; vertex_attributes...) end # of form "faces v1 v2 v3 ...."" diff --git a/src/util.jl b/src/util.jl deleted file mode 100644 index 1c24a8f..0000000 --- a/src/util.jl +++ /dev/null @@ -1,56 +0,0 @@ -# Graphics backends like OpenGL only have one index buffer so the indices to -# positions, normals and texture coordinates cannot be different. E.g. a face -# cannot use positional indices (1, 2, 3) and normal indices (1, 1, 2). In that -# case we need to remap normals such that new_normals[1, 2, 3] = normals[[1, 1, 2]] - - -# ... -_typemin(x) = typemin(x) -_typemin(::Type{OffsetInteger{N, T}}) where {N, T} = typemin(T) - N - -merge_vertex_attribute_indices(faces...) = merge_vertex_attribute_indices(faces) - -function merge_vertex_attribute_indices(faces::Tuple) - FaceType = eltype(faces[1]) - IndexType = eltype(FaceType) - D = length(faces) - N = length(faces[1]) - - # (pos_idx, normal_idx, uv_idx, ...) -> new_idx - vertex_index_map = Dict{NTuple{D, UInt32}, IndexType}() - # faces after remapping (0 based assumed) - new_faces = sizehint!(FaceType[], N) - temp = IndexType[] # keeping track of vertex indices of a face - counter = _typemin(IndexType) - # for remaping attribs, i.e. `new_attrib = old_attrib[index2vertex[attrib_index]]` - index2vertex = ntuple(_ -> sizehint!(UInt32[], N), D) - - for i in eachindex(faces[1]) - # (pos_faces[i], normal_faces[i], uv_faces[i], ...) - attrib_faces = getindex.(faces, i) - empty!(temp) - - for j in eachindex(attrib_faces[1]) - # (pos_index, normal_idx, uv_idx, ...) - # = (pos_faces[i][j], normal_faces[i][j], uv_faces[i][j], ...) - vertex = GeometryBasics.value.(getindex.(attrib_faces, j)) # 1 based - - # if combination of indices in vertex is new, make a new index - if !haskey(vertex_index_map, vertex) - vertex_index_map[vertex] = counter - counter = IndexType(counter + 1) - push!.(index2vertex, vertex) - end - - # keep track of the (new) index for this vertex - push!(temp, vertex_index_map[vertex]) - end - - # store face with new indices - push!(new_faces, FaceType(temp...)) - end - - sizehint!(new_faces, length(new_faces)) - - return new_faces, index2vertex -end \ No newline at end of file From b7739eba44138d6e2a5e8199f6f828013578ff50 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 6 Sep 2024 14:32:00 +0200 Subject: [PATCH 06/22] update stl --- src/io/stl.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/io/stl.jl b/src/io/stl.jl index 6dc838e..d40ee98 100644 --- a/src/io/stl.jl +++ b/src/io/stl.jl @@ -84,7 +84,7 @@ function load(fs::Stream{format"STL_BINARY"}; facetype=GLTriangleFace, i += 1 end - return Mesh(meta(vertices; normals=normals), faces) + return Mesh(vertices, faces; normal = normals) end @@ -127,5 +127,5 @@ function load(fs::Stream{format"STL_ASCII"}; facetype=GLTriangleFace, push!(faces, TriangleFace{Int}(vert_idx...)) end end - return Mesh(meta(points; normals=normals), faces) + return Mesh(points, faces; normal = normals) end From 7658f180632ba884b37df2173107e19076799ee3 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Fri, 6 Sep 2024 19:01:55 +0200 Subject: [PATCH 07/22] update MeshIO --- src/io/gts.jl | 12 +++++------- src/io/ifs.jl | 12 ++++++------ src/io/obj.jl | 26 +++++++++----------------- src/io/ply.jl | 4 ++-- test/runtests.jl | 36 +++++++++++------------------------- 5 files changed, 33 insertions(+), 57 deletions(-) diff --git a/src/io/gts.jl b/src/io/gts.jl index 9c3c33b..88c421e 100644 --- a/src/io/gts.jl +++ b/src/io/gts.jl @@ -12,15 +12,13 @@ function parseGtsLine( s::AbstractString, C, T=eltype(C) ) end end -function load( st::Stream{format"GTS"}, MeshType=GLNormalMesh ) +function load( st::Stream{format"GTS"}; facetype=GLTriangleFace, pointtype=Point) io = stream(st) head = readline( io ) - FT = facetype(MeshType) - VT = vertextype(MeshType) nVertices, nEdges, nFacets = parseGtsLine( head, Tuple{Int,Int,Int} ) iV = iE = iF = 1 - vertices = Vector{VT}(undef, nVertices) + vertices = Vector{pointtype}(undef, nVertices) edges = Vector{Vector{Int}}(undef, nEdges) facets = Vector{Vector{Int}}(undef, nFacets) for full_line::String in eachline(io) @@ -30,7 +28,7 @@ function load( st::Stream{format"GTS"}, MeshType=GLNormalMesh ) if !startswith(line, "#") && !isempty(line) && !all(iscntrl, line) #ignore comments if iV <= nVertices - vertices[iV] = parseGtsLine( line, VT ) + vertices[iV] = parseGtsLine( line, pointtype ) iV += 1 elseif iV > nVertices && iE <= nEdges edges[iE] = parseGtsLine( line, Array{Int} ) @@ -41,8 +39,8 @@ function load( st::Stream{format"GTS"}, MeshType=GLNormalMesh ) end # if end # if end # for - faces = [ FT( union( edges[facets[i][1]], edges[facets[i][2]], edges[facets[i][3]] ) ) for i in 1:length(facets) ] # orientation not guaranteed - return MeshType( vertices, faces ) + faces = [ facetype( union( edges[facets[i][1]], edges[facets[i][2]], edges[facets[i][3]] ) ) for i in 1:length(facets) ] # orientation not guaranteed + return Mesh( vertices, faces ) end function save( st::Stream{format"GTS"}, mesh::AbstractMesh ) diff --git a/src/io/ifs.jl b/src/io/ifs.jl index 2a6c67d..d50a81b 100644 --- a/src/io/ifs.jl +++ b/src/io/ifs.jl @@ -1,4 +1,4 @@ -function load(fs::Stream{format"IFS"}, MeshType = GLNormalMesh) +function load(fs::Stream{format"IFS"}; facetype=GLTriangleFace, pointtype=Point3f) io = stream(fs) function str() n = read(io, UInt32) @@ -11,15 +11,15 @@ function load(fs::Stream{format"IFS"}, MeshType = GLNormalMesh) end nverts = read(io, UInt32) verts_float = read(io, Float32, nverts * 3) - verts = reinterpret(Point3f0, verts_float) + verts = reinterpret(pointtype, verts_float) tris = str() if tris != "TRIANGLES\0" error("$(filename(fs)) does not seem to be of format IFS") end nfaces = read(io, UInt32) faces_int = read(io, UInt32, nfaces * 3) - faces = reinterpret(GLTriangle, faces_int) - MeshType(vertices = verts, faces = faces) + faces = reinterpret(facetype, faces_int) + return GeometryBasics.mesh(vertices = verts, faces = faces) end function save(fs::Stream{format"IFS"}, msh::AbstractMesh; meshname = "mesh") @@ -29,8 +29,8 @@ function save(fs::Stream{format"IFS"}, msh::AbstractMesh; meshname = "mesh") write(io, UInt32(length(s0))) write(io, s0) end - vts = decompose(Point3f0, msh) - fcs = decompose(GLTriangle, msh) + vts = decompose(Point3f, msh) + fcs = decompose(GLTriangleFace, msh) # write the header write0str("IFS") diff --git a/src/io/obj.jl b/src/io/obj.jl index 4101bf3..af25d59 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -5,11 +5,10 @@ ############################## function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, - pointtype=Point3f, normaltype=Vec3f, uvtype=Vec2f) + pointtype=Point3f, normaltype=Vec3f, uvtype=Any) points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], Any[] - last_command = "" - attrib_type = nothing + for full_line in eachline(stream(io)) # read a line, remove newline and leading/trailing whitespaces line = strip(chomp(full_line)) @@ -54,7 +53,7 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, append!(faces, GeometryBasics.UVFace.(pos_faces, uv_faces)) else normal_faces = triangulated_faces(facetype, getindex.(fs, 3)) - append!(faces, GeometryBasics.NormalUVFace.(pos_faces, normal_faces, uv_faces)) + append!(faces, GeometryBasics.UVNormalFace.(pos_faces, uv_faces, normal_faces)) end else append!(faces, triangulated_faces(facetype, lines)) @@ -65,22 +64,15 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, end end - vertex_attributes = Dict{Symbol, Any}() - - # TODO: add GeometryBasics convenience for dropping nothing vertex attributes? - if !isempty(v_normals) - vertex_attributes[:normal] = v_normals - end - - if !isempty(uv) - vertex_attributes[:uv] = uv - end - # TODO: Can we avoid this conversion? # Also, is it safe to do? Or can an obj file define different face types for different groups? faces = convert(Vector{typeof(first(faces))}, faces) - return GeometryBasics.mesh(points, faces, facetype = facetype; vertex_attributes...) + return GeometryBasics.mesh( + points, faces, facetype = facetype; + uv = isempty(uv) ? nothing : uv, + normal = isempty(v_normals) ? nothing : v_normals + ) end # of form "faces v1 v2 v3 ...."" @@ -111,7 +103,7 @@ function save(f::Stream{format"OBJ"}, mesh::AbstractMesh) end end - if hasproperty(mesh, :normals) + if hasproperty(mesh, :normal) for n in decompose_normals(mesh) println(io, "vn ", n[1], " ", n[2], " ", n[3]) end diff --git a/src/io/ply.jl b/src/io/ply.jl index f4a537e..d44f116 100644 --- a/src/io/ply.jl +++ b/src/io/ply.jl @@ -121,7 +121,7 @@ function load(fs::Stream{format"PLY_ASCII"}; facetype=GLTriangleFace, pointtype= end end if has_normals - return Mesh(meta(points; normals=point_normals), faces) + return Mesh(points, faces; normal = point_normals) else return Mesh(points, faces) end @@ -194,7 +194,7 @@ function load(fs::Stream{format"PLY_BINARY"}; facetype=GLTriangleFace, pointtype end if has_normals - return Mesh(meta(points; normals=point_normals), faces) + return Mesh(points, faces; normal = point_normals) else return Mesh(points, faces) end diff --git a/test/runtests.jl b/test/runtests.jl index 70ae35b..b3bf0b9 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,6 +3,8 @@ using Test const tf = joinpath(dirname(@__FILE__), "testfiles") using MeshIO +using GeometryBasics: GLNormalMesh + function test_face_indices(mesh) for face in faces(mesh) for index in face @@ -23,6 +25,8 @@ end ] uvn_mesh = merge(map(uv_normal_mesh, mesh)) mesh = merge(map(triangle_mesh, mesh)) + empty!(uvn_mesh.views) + empty!(mesh.views) mktempdir() do tmpdir @@ -54,6 +58,8 @@ end @test mesh_loaded == uvn_mesh end end + + @testset "Real world files" begin @testset "STL" begin @@ -67,7 +73,7 @@ end @test msh isa GLNormalMesh @test length(faces(msh)) == 828 @test length(coordinates(msh)) == 2484 - @test length(msh.normals) == 2484 + @test length(normals(msh)) == 2484 @test test_face_indices(msh) mktempdir() do tmpdir @@ -76,7 +82,7 @@ end @test msh1 isa GLNormalMesh @test faces(msh) == faces(msh1) @test coordinates(msh) == coordinates(msh1) - @test msh.normals == msh1.normals + @test normals(msh) == normals(msh1) end msh = load(joinpath(tf, "binary_stl_from_solidworks.STL")) @@ -172,29 +178,9 @@ end end @testset "GTS" begin # TODO: FileIO upstream - #msh = load(joinpath(tf, "sphere5.gts")) - #@test typeof(msh) == GLNormalMesh - #test_face_indices(msh) - end - - @testset "Index remapping" begin - pos_faces = GLTriangleFace[(5, 6, 7), (5, 6, 8), (5, 7, 8)] - normal_faces = GLTriangleFace[(5, 6, 7), (3, 6, 8), (5, 7, 8)] - uv_faces = GLTriangleFace[(1, 2, 3), (4, 2, 5), (1, 3, 1)] - - # unique combinations -> new indices - # 551 662 773 534 885 881 1 2 3 4 5 6 (or 0..5 with 0 based indices) - faces, maps = MeshIO.merge_vertex_attribute_indices(pos_faces, normal_faces, uv_faces) - - @test length(faces) == 3 - @test faces == GLTriangleFace[(1, 2, 3), (4, 2, 5), (1, 3, 6)] - - # maps are structured as map[new_index] = old_index, so they grab the - # first/second/third index of the unique combinations above - # maps = (pos_map, normal_map, uv_map) - @test maps[1] == [5, 6, 7, 5, 8, 8] - @test maps[2] == [5, 6, 7, 3, 8, 8] - @test maps[3] == [1, 2, 3, 4, 5, 1] + # msh = load(joinpath(tf, "sphere5.gts")) + # @test typeof(msh) == GLNormalMesh + # test_face_indices(msh) end end end From 78f443becd01285fb479362ab8c172a3d1e10fd2 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 12 Sep 2024 16:35:33 +0200 Subject: [PATCH 08/22] update for FaceView --- src/io/ifs.jl | 2 +- src/io/obj.jl | 34 ++++++++++++++++++---------------- test/runtests.jl | 20 +++++++++++--------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/io/ifs.jl b/src/io/ifs.jl index d50a81b..fedc173 100644 --- a/src/io/ifs.jl +++ b/src/io/ifs.jl @@ -19,7 +19,7 @@ function load(fs::Stream{format"IFS"}; facetype=GLTriangleFace, pointtype=Point3 nfaces = read(io, UInt32) faces_int = read(io, UInt32, nfaces * 3) faces = reinterpret(facetype, faces_int) - return GeometryBasics.mesh(vertices = verts, faces = faces) + return GeometryBasics.Mesh(verts, faces) end function save(fs::Stream{format"IFS"}, msh::AbstractMesh; meshname = "mesh") diff --git a/src/io/obj.jl b/src/io/obj.jl index af25d59..66bf130 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -7,7 +7,8 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, pointtype=Point3f, normaltype=Vec3f, uvtype=Any) - points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], Any[] + points, v_normals, uv, faces = pointtype[], normaltype[], uvtype[], facetype[] + f_uv_n_faces = (faces, facetype[], facetype[]) for full_line in eachline(stream(io)) # read a line, remove newline and leading/trailing whitespaces @@ -41,22 +42,14 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, elseif "f" == command # mesh always has faces if any(x-> occursin("//", x), lines) fs = process_face_normal(lines) - pos_faces = triangulated_faces(facetype, getindex.(fs, 1)) - normal_faces = triangulated_faces(facetype, getindex.(fs, 2)) - append!(faces, GeometryBasics.NormalFace.(pos_faces, normal_faces)) - elseif any(x-> occursin("/", x), lines) fs = process_face_uv_or_normal(lines) - pos_faces = triangulated_faces(facetype, getindex.(fs, 1)) - uv_faces = triangulated_faces(facetype, getindex.(fs, 2)) - if length(fs[1]) == 2 - append!(faces, GeometryBasics.UVFace.(pos_faces, uv_faces)) - else - normal_faces = triangulated_faces(facetype, getindex.(fs, 3)) - append!(faces, GeometryBasics.UVNormalFace.(pos_faces, uv_faces, normal_faces)) - end else append!(faces, triangulated_faces(facetype, lines)) + continue + end + for i = 1:length(first(fs)) + append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i))) end else #TODO @@ -64,9 +57,13 @@ function load(io::Stream{format"OBJ"}; facetype=GLTriangleFace, end end - # TODO: Can we avoid this conversion? - # Also, is it safe to do? Or can an obj file define different face types for different groups? - faces = convert(Vector{typeof(first(faces))}, faces) + if !isempty(f_uv_n_faces[2]) && (f_uv_n_faces[2] != faces) + uv = FaceView(uv, f_uv_n_faces[2]) + end + + if !isempty(f_uv_n_faces[3]) && (f_uv_n_faces[3] != faces) + v_normals = FaceView(v_normals, f_uv_n_faces[3]) + end return GeometryBasics.mesh( points, faces, facetype = facetype; @@ -92,6 +89,11 @@ function _typemax(::Type{OffsetInteger{O, T}}) where {O, T} end function save(f::Stream{format"OBJ"}, mesh::AbstractMesh) + # TODO: allow saving with faceviews (i.e. build the / or // syntax) + if any(v -> v isa FaceView, values(vertex_attributes(mesh))) + mesh = GeometryBasics.clear_faceviews(mesh) + end + io = stream(f) for p in decompose(Point3f, mesh) println(io, "v ", p[1], " ", p[2], " ", p[3]) diff --git a/test/runtests.jl b/test/runtests.jl index b3bf0b9..51db14c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,8 +3,6 @@ using Test const tf = joinpath(dirname(@__FILE__), "testfiles") using MeshIO -using GeometryBasics: GLNormalMesh - function test_face_indices(mesh) for face in faces(mesh) for index in face @@ -23,8 +21,8 @@ end Rect3f(Vec3f(baselen), Vec3f(baselen, dirlen, baselen)), Rect3f(Vec3f(baselen), Vec3f(baselen, baselen, dirlen)) ] - uvn_mesh = merge(map(uv_normal_mesh, mesh)) - mesh = merge(map(triangle_mesh, mesh)) + uvn_mesh = GeometryBasics.clear_faceviews(merge(map(uv_normal_mesh, mesh))) + mesh = GeometryBasics.clear_faceviews(merge(map(triangle_mesh, mesh))) empty!(uvn_mesh.views) empty!(mesh.views) @@ -70,7 +68,8 @@ end @test test_face_indices(msh) msh = load(joinpath(tf, "binary.stl")) - @test msh isa GLNormalMesh + @test msh isa Mesh{D, Float32, GLTriangleFace} where D + @test all(v -> v isa AbstractVector, values(vertex_attributes(msh))) @test length(faces(msh)) == 828 @test length(coordinates(msh)) == 2484 @test length(normals(msh)) == 2484 @@ -79,14 +78,16 @@ end mktempdir() do tmpdir save(File{format"STL_BINARY"}(joinpath(tmpdir, "test.stl")), msh) msh1 = load(joinpath(tmpdir, "test.stl")) - @test msh1 isa GLNormalMesh + @test msh1 isa Mesh{D, Float32, GLTriangleFace} where D + @test all(v -> v isa AbstractVector, values(vertex_attributes(msh1))) @test faces(msh) == faces(msh1) @test coordinates(msh) == coordinates(msh1) @test normals(msh) == normals(msh1) end msh = load(joinpath(tf, "binary_stl_from_solidworks.STL")) - @test msh isa GLNormalMesh + @test msh isa Mesh{D, Float32, GLTriangleFace} where D + @test all(v -> v isa AbstractVector, values(vertex_attributes(msh))) @test length(faces(msh)) == 12 @test length(coordinates(msh)) == 36 @test test_face_indices(msh) @@ -139,8 +140,9 @@ end @testset "OBJ" begin msh = load(joinpath(tf, "test.obj")) @test length(faces(msh)) == 3954 - @test length(coordinates(msh)) == 2519 - @test length(normals(msh)) == 2519 + @test length(coordinates(msh)) == 2248 + @test length(normals(msh)) == 2240 + @test length(texturecoordinates(msh)) == 2220 @test test_face_indices(msh) msh = load(joinpath(tf, "cube.obj")) # quads From 6ed5a79f7f9a81ff46883b21625821cb9da5017e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Sun, 15 Sep 2024 21:54:35 +0200 Subject: [PATCH 09/22] change origin offset -> offset --- src/io/obj.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index afebff3..7f7e925 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -353,11 +353,12 @@ function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String return materials end +# TODO: Consider generating a ShaderAbstractions Sampler? function parse_texture_info(parent_path::String, lines::Vector{SubString{String}}) idx = 1 output = Dict{String, Any}() name_lookup = Dict( - "o" => "origin offset", "s" => "scale", "t" => "turbulence", + "o" => "offset", "s" => "scale", "t" => "turbulence", "blendu" => "blend horizontal", "blendv" => "blend vertical", "boost" => "mipmap sharpness", "bm" => "bump multiplier" ) From 64d624d8611c878e49c7c3bc9a58be873116b9de Mon Sep 17 00:00:00 2001 From: Frederic Freyer Date: Mon, 16 Sep 2024 05:19:12 +0200 Subject: [PATCH 10/22] remove redundant split_mesh function --- src/io/obj.jl | 55 +-------------------------------------------------- 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index 7f7e925..c9a4c0b 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -214,59 +214,6 @@ function save(f::Stream{format"OBJ"}, mesh::AbstractMesh) end -# Experimental stuff for loading .mtl files and working with multiple materials - -""" - MehsIO.split_mesh(mesh) - -Experimental function for splitting a mesh based material indices. -Also remaps vertices to avoid passing all vertices with a submesh. -""" -function split_mesh(mesh) - ps = coordinates(mesh) - ns = normals(mesh) - uvs = texturecoordinates(mesh) - ids = mesh.material - fs = faces(mesh) - - meshes = Dict{Int, Any}() - target_ids = unique(ids) - IndexType = eltype(eltype(fs)) - - for target_id in target_ids - _fs = eltype(fs)[] - indexmap = Dict{UInt32, UInt32}() - counter = MeshIO._typemin(IndexType) - - for f in fs - if any(ids[f] .== target_id) - f = map(f) do _i - i = GeometryBasics.value(_i) - if haskey(indexmap, i) - return indexmap[i] - else - indexmap[i] = counter - counter += 1 - return counter-1 - end - end - push!(_fs, f) - end - end - - indices = Vector{UInt32}(undef, counter-1) - for (old, new) in indexmap - indices[new] = old - end - - meshes[target_id] = GeometryBasics.Mesh( - meta(ps[indices], normals = ns[indices], uv = uvs[indices]), _fs - ) - end - - return meshes -end - function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String) endswith(filename, ".mtl") || error("Material Template Library $filename must be a .mtl file.") @@ -442,4 +389,4 @@ function parse_texture_info(parent_path::String, lines::Vector{SubString{String} end return output -end \ No newline at end of file +end From 9a834c4cfdc3ed81ebcbc7a7878ebf6d6e72e8d7 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Thu, 3 Oct 2024 20:57:30 +0200 Subject: [PATCH 11/22] add transmission filter & allow simultaneous alpha + transmission --- src/io/obj.jl | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index 7f7e925..fcf162f 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -150,7 +150,7 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, try _load_mtl!(materials, joinpath(path, filename)) catch e - @error exception = e + @error "While parsing $(joinpath(path, filename)):" exception = e end end metadata[:materials] = materials @@ -280,6 +280,7 @@ function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String "Pc" => "clearcoat thickness", "Pcr" => "clearcoat roughness", "Ke" => "emissive", "aniso" => "anisotropy", "anisor" => "anisotropy rotation", + "Tf" => "transmission filter", # texture maps "map_Ka" => "ambient map", "map_Kd" => "diffuse map", "map_Ks" => "specular map", "map_Ns" => "shininess map", @@ -290,7 +291,7 @@ function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String "map_Pr" => "roughness map", "map_Pm" => "metallic map", "map_Ps" => "sheen map", "map_Ke" => "emissive map", "map_RMA" => "roughness metalness occlusion map", - "map_ORM" => "occlusion roughness metalness map" + "map_ORM" => "occlusion roughness metalness map", ) path = joinpath(splitpath(filename)[1:end-1]) @@ -318,17 +319,23 @@ function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String elseif command == "Ns" || command == "Ni" || command == "Pr" || command == "Pm" || command == "Ps" || command == "Pc" || command == "Pcr" || command == "Ke" || command == "aniso" || - command == "anisor" + command == "anisor" || command == "Tf" material[name_lookup[command]] = parse.(Float32, lines[1]) elseif command == "d" - haskey(material, "alpha") && error("Material alpha doubly defined.") - material[name_lookup[command]] = parse.(Float32, lines[1]) + alpha = parse.(Float32, lines[1]) + if haskey(material, "alpha") && !(material["alpha"] ≈ alpha) + @error("Material alpha doubly defined. Overwriting $(material["alpha"]) with $alpha.") + end + material[name_lookup[command]] = alpha elseif command == "Tr" - haskey(material, "alpha") && error("Material alpha doubly defined.") - material[name_lookup["d"]] = 1f0 - parse.(Float32, lines[1]) + alpha = 1f0 - parse.(Float32, lines[1]) + if haskey(material, "alpha") && !(material["alpha"] ≈ alpha) + @error("Material alpha doubly defined. Overwriting $(material["alpha"]) with $alpha") + end + material[name_lookup["d"]] = alpha # elseif Tf # transmission filter From 41f813da3f43429620e374e9a052f97245b8989c Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 21 Oct 2024 18:17:03 +0200 Subject: [PATCH 12/22] skip material and return basic Mesh if no mtl files found --- src/io/obj.jl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/io/obj.jl b/src/io/obj.jl index 9f01103..f5f2ea6 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -146,6 +146,13 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, # Load material files materials = Dict{String, Dict{String, Any}}() path = joinpath(splitpath(FileIO.filename(fn))[1:end-1]) + + # Fallback - if no mtl file exists abort and return just the mesh + if !any(filename -> isfile(joinpath(path, filename)), mtllibs) + @error "obj file contains references to .mtl files, but none could be found. Expected: $mtllibs in $path." + return mesh + end + for filename in mtllibs try _load_mtl!(materials, joinpath(path, filename)) From c9041d3e99abc7c926050888865592b71d00c249 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 21 Oct 2024 18:58:59 +0200 Subject: [PATCH 13/22] 1.6 compat --- src/io/obj.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index f5f2ea6..094b533 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -145,7 +145,7 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, # Load material files materials = Dict{String, Dict{String, Any}}() - path = joinpath(splitpath(FileIO.filename(fn))[1:end-1]) + path = joinpath(splitpath(FileIO.filename(fn))[1:end-1]...) # Fallback - if no mtl file exists abort and return just the mesh if !any(filename -> isfile(joinpath(path, filename)), mtllibs) From fd21113f0ad8eb1a09ad3b33632ac07fdb0cab05 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 21 Oct 2024 23:16:24 +0200 Subject: [PATCH 14/22] more 1.6 compat --- src/io/obj.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index 094b533..4c7dfb5 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -248,7 +248,7 @@ function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String "map_ORM" => "occlusion roughness metalness map", ) - path = joinpath(splitpath(filename)[1:end-1]) + path = joinpath(splitpath(filename)[1:end-1]...) open(filename, "r") do file # Just so the variable is defined From ef2801e90ef47c407d8595727232df2c13c878de Mon Sep 17 00:00:00 2001 From: Frederic Freyer Date: Mon, 18 Nov 2024 14:44:13 +0100 Subject: [PATCH 15/22] bump GeometryBasics version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index ae7134f..33d75c6 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,7 @@ Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" [compat] ColorTypes = "0.8, 0.9, 0.10, 0.11" FileIO = "1.2.4" -GeometryBasics = "0.4.1" +GeometryBasics = "0.5" julia = "1.3" [extras] From ebe5c38d72209160b1f7e5884a01e8d909e81f34 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 16:57:55 +0100 Subject: [PATCH 16/22] fix renamed function --- test/runtests.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 51db14c..97f6137 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,8 +21,8 @@ end Rect3f(Vec3f(baselen), Vec3f(baselen, dirlen, baselen)), Rect3f(Vec3f(baselen), Vec3f(baselen, baselen, dirlen)) ] - uvn_mesh = GeometryBasics.clear_faceviews(merge(map(uv_normal_mesh, mesh))) - mesh = GeometryBasics.clear_faceviews(merge(map(triangle_mesh, mesh))) + uvn_mesh = GeometryBasics.expand_faceviews(merge(map(uv_normal_mesh, mesh))) + mesh = GeometryBasics.expand_faceviews(merge(map(triangle_mesh, mesh))) empty!(uvn_mesh.views) empty!(mesh.views) @@ -152,7 +152,7 @@ end msh = load(joinpath(tf, "cube_uv.obj")) @test typeof(msh.uv) == Vector{Vec{2,Float32}} - @test length(msh.uv) == 8 + @test length(msh.uv) == 8 msh = load(joinpath(tf, "cube_uvw.obj")) @test typeof(msh.uv) == Vector{Vec{3,Float32}} From 79cbc3f8aa196fed73de17330605bd423c0080e8 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 17:03:29 +0100 Subject: [PATCH 17/22] update CI to 1.6, 1 and avoid running twice --- .github/workflows/CI.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e2bf9be..2e7edcb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,7 +1,12 @@ name: CI on: - - push - - pull_request + push: + branches: + - master + tags: "*" + pull_request: + branches: + - master jobs: test: name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} @@ -10,8 +15,8 @@ jobs: fail-fast: false matrix: version: - - '1.3' - '1.6' + - '1' os: - ubuntu-latest arch: From 4f8321697246a52d97fac059bd2cf1614083be61 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 18:39:53 +0100 Subject: [PATCH 18/22] add partial Sponza model for testing --- test/runtests.jl | 43 +++ test/testfiles/mini sponza/copyright.txt | 8 + test/testfiles/mini sponza/sponza.mtl | 316 +++++++++++++++++ test/testfiles/mini sponza/sponza.obj | 409 +++++++++++++++++++++++ 4 files changed, 776 insertions(+) create mode 100644 test/testfiles/mini sponza/copyright.txt create mode 100644 test/testfiles/mini sponza/sponza.mtl create mode 100644 test/testfiles/mini sponza/sponza.obj diff --git a/test/runtests.jl b/test/runtests.jl index 97f6137..5938b77 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -184,5 +184,48 @@ end # @test typeof(msh) == GLNormalMesh # test_face_indices(msh) end + + @testset "Partial Sponza (OBJ)" begin + # reduced version of the Sponza model from https://casual-effects.com/data/ + # Contains one sub-mesh and all materials + msh = load(joinpath(tf, "mini sponza/sponza.obj")) + + @test msh isa MetaMesh + @test length(faces(msh)) == 192 + @test length(coordinates(msh)) == 150 + @test length(texturecoordinates(msh)) == 150 + @test msh.views == [0x00000001:0x000000c0] + @test test_face_indices(msh) + + # :groups, :material_names are in sync with views + @test haskey(msh, :groups) + @test msh[:groups] == ["arcs_floor"] + @test haskey(msh, :material_names) + @test msh[:material_names] == ["sp_00_luk_mali"] + + # :materials are all of them + @test haskey(msh, :materials) + material_names = ["sp_01_stup", "sp_svod_kapitel", "sp_vijenac", "sp_00_pod", "sp_02_reljef", "sp_00_vrata_kock", "sp_zid_vani", "sp_00_vrata_krug", "sp_01_stub_baza", "sp_01_stub", "sp_00_luk_mali", "sp_01_stub_kut", "sp_00_svod", "sp_00_luk_mal1", "sp_00_zid", "sp_00_prozor", "sp_01_luk_a", "sp_00_stup", "sp_01_stub_baza_", "sp_01_stup_baza"] + @test all(k -> haskey(msh[:materials], k), material_names) + + # Test one explicitly + material = msh[:materials]["sp_00_luk_mali"] + @test material["refractive index"] == 1.5 + @test material["diffuse"] == Vec3f(0.745098, 0.709804, 0.67451) + @test material["transmission filter"] == 1.0 + @test material["ambient"] == Vec3f(0.0, 0.0, 0.0) + @test material["specular"] == Vec3f(0.0, 0.0, 0.0) + @test material["alpha"] == 1.0 + @test material["illumination model"] == 2 + @test material["shininess"] == 50.0 + @test material["emissive"] == 0.0 + + @test material["bump map"] isa Dict{String, Any} + @test material["bump map"]["filename"] == replace(joinpath(tf, "mini sponza/sp_luk-bump.JPG"), '\\' => '/') + @test material["ambient map"] isa Dict{String, Any} + @test material["ambient map"]["filename"] == replace(joinpath(tf, "mini sponza/SP_LUK.JPG"), '\\' => '/') + @test material["diffuse map"] isa Dict{String, Any} + @test material["diffuse map"]["filename"] == replace(joinpath(tf, "mini sponza/SP_LUK.JPG"), '\\' => '/') + end end end diff --git a/test/testfiles/mini sponza/copyright.txt b/test/testfiles/mini sponza/copyright.txt new file mode 100644 index 0000000..bc4d4b6 --- /dev/null +++ b/test/testfiles/mini sponza/copyright.txt @@ -0,0 +1,8 @@ +http://hdri.cgtechniques.com/~sponza/files/ + +Sponza modeled by Marko Dabrovic, with UVs and crack errors fixed by Kenzie Lamar at Vicarious Visions. +Bump maps painted by Morgan McGuire. + +--- + +Downloaded from https://casual-effects.com/data/ \ No newline at end of file diff --git a/test/testfiles/mini sponza/sponza.mtl b/test/testfiles/mini sponza/sponza.mtl new file mode 100644 index 0000000..be0160e --- /dev/null +++ b/test/testfiles/mini sponza/sponza.mtl @@ -0,0 +1,316 @@ +# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware +# File Created: 26.07.2011 17:00:30 + +newmtl sp_00_luk_mali + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.745098 0.709804 0.674510 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka SP_LUK.JPG + map_Kd SP_LUK.JPG + map_bump sp_luk-bump.JPG + bump sp_luk-bump.JPG + +newmtl sp_svod_kapitel + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.713726 0.705882 0.658824 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 00_SKAP.JPG + map_Kd 00_SKAP.JPG + map_bump 00_SKAP.JPG + bump 00_SKAP.JPG + +newmtl sp_01_stub_baza_ + Ns 19.999998 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.784314 0.784314 0.784314 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + +newmtl sp_01_stub_kut + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.737255 0.709804 0.670588 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 01_STUB.JPG + map_Kd 01_STUB.JPG + map_bump 01_STUB-bump.jpg + bump 01_STUB-bump.jpg + +newmtl sp_00_stup + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.737255 0.709804 0.670588 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 01_STUB.JPG + map_Kd 01_STUB.JPG + map_bump 01_STUB-bump.jpg + bump 01_STUB-bump.jpg + +newmtl sp_01_stub_baza + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.800000 0.784314 0.749020 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 01_S_BA.JPG + map_Kd 01_S_BA.JPG + map_bump 01_S_BA.JPG + bump 01_S_BA.JPG + +newmtl sp_00_luk_mal1 + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.745098 0.709804 0.674510 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 01_ST_KP.JPG + map_Kd 01_ST_KP.JPG + map_bump 01_St_kp-bump.jpg + bump 01_St_kp-bump.jpg + +newmtl sp_01_stub + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.737255 0.709804 0.670588 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 01_STUB.JPG + map_Kd 01_STUB.JPG + map_bump 01_STUB-bump.jpg + bump 01_STUB-bump.jpg + +newmtl sp_01_stup + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.827451 0.800000 0.768628 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka X01_ST.JPG + map_Kd X01_ST.JPG + +newmtl sp_vijenac + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.713726 0.705882 0.658824 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 00_SKAP.JPG + map_Kd 00_SKAP.JPG + map_bump 00_SKAP.JPG + bump 00_SKAP.JPG + +newmtl sp_00_svod + Ns 1.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.145098 0.145098 0.145098 + Kd 0.941177 0.866667 0.737255 + Ks 0.034039 0.032314 0.029333 + Ke 0.000000 0.000000 0.000000 + map_Kd KAMEN-stup.JPG + map_Ka KAMEN-stup.JPG + map_bump KAMEN-stup.jpg + bump KAMEN-stup.jpg + +newmtl sp_02_reljef + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.529412 0.498039 0.490196 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka RELJEF.JPG + map_Kd RELJEF.JPG + map_bump reljef-bump.jpg + bump reljef-bump.jpg + +newmtl sp_01_luk_a + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.745098 0.709804 0.674510 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka SP_LUK.JPG + map_Kd SP_LUK.JPG + map_bump sp_luk-bump.JPG + bump sp_luk-bump.JPG + +newmtl sp_zid_vani + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.627451 0.572549 0.560784 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka KAMEN.JPG + map_Kd KAMEN.JPG + map_bump KAMEN-bump.jpg + bump KAMEN-bump.jpg + +newmtl sp_01_stup_baza + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.800000 0.784314 0.749020 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka 01_S_BA.JPG + map_Kd 01_S_BA.JPG + map_bump 01_S_BA.JPG + bump 01_S_BA.JPG + +newmtl sp_00_zid + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.627451 0.572549 0.560784 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka KAMEN.JPG + map_Kd KAMEN.JPG + map_bump KAMEN-bump.jpg + bump KAMEN-bump.jpg + +newmtl sp_00_prozor + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 1.000000 1.000000 1.000000 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka PROZOR1.JPG + map_Kd PROZOR1.JPG + map_bump PROZOR1.JPG + bump PROZOR1.JPG + +newmtl sp_00_vrata_krug + Ns 19.999998 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.784314 0.784314 0.784314 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka VRATA_KR.JPG + map_Kd VRATA_KR.JPG + map_bump VRATA_KR.JPG + bump VRATA_KR.JPG + +newmtl sp_00_pod + Ns 50.000000 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.627451 0.572549 0.560784 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka KAMEN.JPG + map_Kd KAMEN.JPG + map_bump KAMEN-bump.jpg + bump KAMEN-bump.jpg + +newmtl sp_00_vrata_kock + Ns 19.999998 + Ni 1.500000 + d 1.000000 + Tr 0.000000 + Tf 1.000000 1.000000 1.000000 + illum 2 + Ka 0.000000 0.000000 0.000000 + Kd 0.784314 0.784314 0.784314 + Ks 0.000000 0.000000 0.000000 + Ke 0.000000 0.000000 0.000000 + map_Ka VRATA_KO.JPG + map_Kd VRATA_KO.JPG + map_bump VRATA_KO.JPG + bump VRATA_KO.JPG diff --git a/test/testfiles/mini sponza/sponza.obj b/test/testfiles/mini sponza/sponza.obj new file mode 100644 index 0000000..982d541 --- /dev/null +++ b/test/testfiles/mini sponza/sponza.obj @@ -0,0 +1,409 @@ +mtllib sponza.mtl + +# +# object arcs_floor +# + +v 10.927240 2.957242 2.370587 +v 10.927240 3.238548 2.282929 +v 10.927240 3.149897 2.049175 +v 10.927240 2.897413 2.127851 +v 11.587240 3.149897 2.049175 +v 11.587240 2.897413 2.127851 +v 10.927240 3.507237 2.162002 +v 10.927240 3.391056 1.940638 +v 11.587240 3.391056 1.940638 +v 10.927240 3.759390 2.009570 +v 10.927240 3.617374 1.803824 +v 11.587240 3.617374 1.803824 +v 10.927240 3.991331 1.827855 +v 10.927240 3.825550 1.640728 +v 11.587240 3.825551 1.640728 +v 10.927240 4.199678 1.619508 +v 10.927240 4.012550 1.453728 +v 11.587240 4.012550 1.453728 +v 10.927240 4.381392 1.387567 +v 10.927240 4.175646 1.245551 +v 11.587240 4.175646 1.245551 +v 10.927240 4.533824 1.135414 +v 10.927240 4.312460 1.019233 +v 11.587240 4.312460 1.019233 +v 10.927240 4.654751 0.866725 +v 10.927240 4.420997 0.778074 +v 11.587240 4.420997 0.778074 +v 10.927240 4.742409 0.585419 +v 10.927240 4.499674 0.525590 +v 11.587240 4.499674 0.525590 +v 10.927240 4.795521 0.295599 +v 10.927240 4.547344 0.265464 +v 11.587240 4.547344 0.265464 +v 10.927240 4.813311 0.001489 +v 10.927240 4.563311 0.001489 +v 11.587240 4.563312 0.001489 +v 10.927240 4.795521 -0.292620 +v 10.927240 4.547344 -0.262486 +v 11.587240 4.547344 -0.262486 +v 10.927240 4.742409 -0.582441 +v 10.927240 4.499674 -0.522612 +v 11.587240 4.499674 -0.522612 +v 10.927240 4.654750 -0.863747 +v 10.927240 4.420997 -0.775095 +v 11.587240 4.420997 -0.775095 +v 10.927240 4.533823 -1.132435 +v 10.927240 4.312460 -1.016254 +v 11.587240 4.312460 -1.016254 +v 10.927240 4.381392 -1.384588 +v 10.927240 4.175646 -1.242572 +v 11.587240 4.175646 -1.242572 +v 10.927240 4.199677 -1.616530 +v 10.927240 4.012550 -1.450749 +v 11.587240 4.012550 -1.450749 +v 10.927240 3.991331 -1.824877 +v 10.927240 3.825550 -1.637749 +v 11.587240 3.825550 -1.637749 +v 10.927240 3.759389 -2.006591 +v 10.927240 3.617373 -1.800845 +v 11.587240 3.617373 -1.800845 +v 10.927240 3.507236 -2.159023 +v 10.927240 3.391055 -1.937659 +v 11.587240 3.391055 -1.937659 +v 10.927240 3.238547 -2.279950 +v 10.927240 3.149896 -2.046196 +v 11.587240 3.149896 -2.046196 +v 10.927240 2.957242 -2.367608 +v 10.927240 2.897413 -2.124873 +v 11.587240 2.897413 -2.124873 +v 10.927240 2.693312 2.165255 +v 10.927240 2.693312 2.418954 +v 11.587240 2.693312 2.165255 +v 10.927240 2.693311 -2.415975 +v 10.927240 2.693311 -2.162276 +v 11.587240 2.693311 -2.162276 +v -10.912760 3.149897 2.049175 +v -10.912760 3.238548 2.282929 +v -10.912760 2.957242 2.370587 +v -10.912760 2.897413 2.127851 +v -11.572760 2.897413 2.127851 +v -11.572760 3.149897 2.049175 +v -10.912760 3.391056 1.940638 +v -10.912760 3.507237 2.162002 +v -11.572760 3.391056 1.940638 +v -10.912760 3.617374 1.803824 +v -10.912760 3.759390 2.009570 +v -11.572760 3.617374 1.803824 +v -10.912760 3.825550 1.640728 +v -10.912760 3.991331 1.827855 +v -11.572760 3.825551 1.640728 +v -10.912760 4.012550 1.453728 +v -10.912760 4.199678 1.619508 +v -11.572760 4.012550 1.453728 +v -10.912760 4.175646 1.245551 +v -10.912760 4.381392 1.387567 +v -11.572760 4.175646 1.245551 +v -10.912760 4.312460 1.019233 +v -10.912760 4.533824 1.135414 +v -11.572760 4.312460 1.019233 +v -10.912760 4.420997 0.778074 +v -10.912760 4.654751 0.866725 +v -11.572760 4.420997 0.778074 +v -10.912760 4.499674 0.525590 +v -10.912760 4.742409 0.585419 +v -11.572760 4.499674 0.525590 +v -10.912760 4.547344 0.265464 +v -10.912760 4.795521 0.295599 +v -11.572760 4.547344 0.265464 +v -10.912760 4.563311 0.001489 +v -10.912760 4.813311 0.001489 +v -11.572760 4.563312 0.001489 +v -10.912760 4.795521 -0.292620 +v -10.912760 4.547344 -0.262486 +v -11.572760 4.547344 -0.262486 +v -10.912760 4.742409 -0.582441 +v -10.912760 4.499674 -0.522612 +v -11.572760 4.499674 -0.522612 +v -10.912760 4.654750 -0.863747 +v -10.912760 4.420997 -0.775095 +v -11.572760 4.420997 -0.775095 +v -10.912760 4.533823 -1.132435 +v -10.912760 4.312460 -1.016254 +v -11.572760 4.312460 -1.016254 +v -10.912760 4.381392 -1.384588 +v -10.912760 4.175646 -1.242572 +v -11.572760 4.175646 -1.242572 +v -10.912760 4.199677 -1.616530 +v -10.912760 4.012550 -1.450749 +v -11.572760 4.012550 -1.450749 +v -10.912760 3.991331 -1.824877 +v -10.912760 3.825550 -1.637749 +v -11.572760 3.825550 -1.637749 +v -10.912760 3.759389 -2.006591 +v -10.912760 3.617373 -1.800845 +v -11.572760 3.617373 -1.800845 +v -10.912760 3.507236 -2.159023 +v -10.912760 3.391055 -1.937659 +v -11.572760 3.391055 -1.937659 +v -10.912760 3.238547 -2.279950 +v -10.912760 3.149896 -2.046196 +v -11.572760 3.149896 -2.046196 +v -10.912760 2.957242 -2.367608 +v -10.912760 2.897413 -2.124873 +v -11.572760 2.897413 -2.124873 +v -10.912760 2.693312 2.418954 +v -10.912760 2.693312 2.165255 +v -11.572760 2.693312 2.165255 +v -10.912760 2.693311 -2.162276 +v -10.912760 2.693311 -2.415975 +v -11.572760 2.693311 -2.162276 +# 150 vertices + +vt 0.036923 1.000000 0.000000 +vt 0.075385 1.000000 0.000000 +vt 0.075385 0.900000 0.000000 +vt 0.036923 0.900000 0.000000 +vt 0.075385 0.120000 0.000000 +vt 0.036923 0.120000 0.000000 +vt 0.113846 1.000000 0.000000 +vt 0.113846 0.900000 0.000000 +vt 0.113846 0.120000 0.000000 +vt 0.152308 1.000000 0.000000 +vt 0.152308 0.900000 0.000000 +vt 0.152308 0.120000 0.000000 +vt 0.190769 1.000000 0.000000 +vt 0.190769 0.900000 0.000000 +vt 0.190769 0.120000 0.000000 +vt 0.229231 1.000000 0.000000 +vt 0.229231 0.900000 0.000000 +vt 0.229231 0.120000 0.000000 +vt 0.267692 1.000000 0.000000 +vt 0.267692 0.900000 0.000000 +vt 0.267692 0.120000 0.000000 +vt 0.306154 1.000000 0.000000 +vt 0.306154 0.900000 0.000000 +vt 0.306154 0.120000 0.000000 +vt 0.344615 1.000000 0.000000 +vt 0.344615 0.900000 0.000000 +vt 0.344615 0.120000 0.000000 +vt 0.383077 1.000000 0.000000 +vt 0.383077 0.900000 0.000000 +vt 0.383077 0.120000 0.000000 +vt 0.421538 1.000000 0.000000 +vt 0.421538 0.900000 0.000000 +vt 0.421538 0.120000 0.000000 +vt 0.460000 1.000000 0.000000 +vt 0.460000 0.900000 0.000000 +vt 0.460000 0.120000 0.000000 +vt 0.498462 1.000000 0.000000 +vt 0.498462 0.900000 0.000000 +vt 0.498462 0.120000 0.000000 +vt 0.536923 1.000000 0.000000 +vt 0.536923 0.900000 0.000000 +vt 0.536923 0.120000 0.000000 +vt 0.575385 1.000000 0.000000 +vt 0.575385 0.900000 0.000000 +vt 0.575385 0.120000 0.000000 +vt 0.613846 1.000000 0.000000 +vt 0.613846 0.900000 0.000000 +vt 0.613846 0.120000 0.000000 +vt 0.652308 1.000000 0.000000 +vt 0.652308 0.900000 0.000000 +vt 0.652308 0.120000 0.000000 +vt 0.690769 1.000000 0.000000 +vt 0.690769 0.900000 0.000000 +vt 0.690769 0.120000 0.000000 +vt 0.729231 1.000000 0.000000 +vt 0.729231 0.900000 0.000000 +vt 0.729231 0.120000 0.000000 +vt 0.767692 1.000000 0.000000 +vt 0.767692 0.900000 0.000000 +vt 0.767692 0.120000 0.000000 +vt 0.806154 1.000000 0.000000 +vt 0.806154 0.900000 0.000000 +vt 0.806154 0.120000 0.000000 +vt 0.844615 1.000000 0.000000 +vt 0.844615 0.900000 0.000000 +vt 0.844615 0.120000 0.000000 +vt 0.883077 1.000000 0.000000 +vt 0.883077 0.900000 0.000000 +vt 0.883077 0.120000 0.000000 +vt 0.006745 0.900000 0.000000 +vt 0.001897 1.000000 0.000000 +vt 0.006745 0.120000 0.000000 +vt 0.918103 1.000000 0.000000 +vt 0.913255 0.900000 0.000000 +vt 0.913255 0.120000 0.000000 +vt 0.075385 0.900000 0.000000 +vt 0.075385 1.000000 0.000000 +vt 0.036923 1.000000 0.000000 +vt 0.036923 0.900000 0.000000 +vt 0.036923 0.120000 0.000000 +vt 0.075385 0.120000 0.000000 +vt 0.113846 0.900000 0.000000 +vt 0.113846 1.000000 0.000000 +vt 0.113846 0.120000 0.000000 +vt 0.152308 0.900000 0.000000 +vt 0.152308 1.000000 0.000000 +vt 0.152308 0.120000 0.000000 +vt 0.190769 0.900000 0.000000 +vt 0.190769 1.000000 0.000000 +vt 0.190769 0.120000 0.000000 +vt 0.229231 0.900000 0.000000 +vt 0.229231 1.000000 0.000000 +vt 0.229231 0.120000 0.000000 +vt 0.267692 0.900000 0.000000 +vt 0.267692 1.000000 0.000000 +vt 0.267692 0.120000 0.000000 +vt 0.306154 0.900000 0.000000 +vt 0.306154 1.000000 0.000000 +vt 0.306154 0.120000 0.000000 +vt 0.344615 0.900000 0.000000 +vt 0.344615 1.000000 0.000000 +vt 0.344615 0.120000 0.000000 +vt 0.383077 0.900000 0.000000 +vt 0.383077 1.000000 0.000000 +vt 0.383077 0.120000 0.000000 +vt 0.421538 0.900000 0.000000 +vt 0.421538 1.000000 0.000000 +vt 0.421538 0.120000 0.000000 +vt 0.460000 0.900000 0.000000 +vt 0.460000 1.000000 0.000000 +vt 0.460000 0.120000 0.000000 +vt 0.498462 1.000000 0.000000 +vt 0.498462 0.900000 0.000000 +vt 0.498462 0.120000 0.000000 +vt 0.536923 1.000000 0.000000 +vt 0.536923 0.900000 0.000000 +vt 0.536923 0.120000 0.000000 +vt 0.575385 1.000000 0.000000 +vt 0.575385 0.900000 0.000000 +vt 0.575385 0.120000 0.000000 +vt 0.613846 1.000000 0.000000 +vt 0.613846 0.900000 0.000000 +vt 0.613846 0.120000 0.000000 +vt 0.652308 1.000000 0.000000 +vt 0.652308 0.900000 0.000000 +vt 0.652308 0.120000 0.000000 +vt 0.690769 1.000000 0.000000 +vt 0.690769 0.900000 0.000000 +vt 0.690769 0.120000 0.000000 +vt 0.729231 1.000000 0.000000 +vt 0.729231 0.900000 0.000000 +vt 0.729231 0.120000 0.000000 +vt 0.767692 1.000000 0.000000 +vt 0.767692 0.900000 0.000000 +vt 0.767692 0.120000 0.000000 +vt 0.806154 1.000000 0.000000 +vt 0.806154 0.900000 0.000000 +vt 0.806154 0.120000 0.000000 +vt 0.844615 1.000000 0.000000 +vt 0.844615 0.900000 0.000000 +vt 0.844615 0.120000 0.000000 +vt 0.883077 1.000000 0.000000 +vt 0.883077 0.900000 0.000000 +vt 0.883077 0.120000 0.000000 +vt 0.001897 1.000000 0.000000 +vt 0.006745 0.900000 0.000000 +vt 0.006745 0.120000 0.000000 +vt 0.913255 0.900000 0.000000 +vt 0.918103 1.000000 0.000000 +vt 0.913255 0.120000 0.000000 +# 150 texture coords + +g arcs_floor +usemtl sp_00_luk_mali +f 1/1 2/2 3/3 4/4 +f 3/3 5/5 6/6 4/4 +f 2/2 7/7 8/8 3/3 +f 8/8 9/9 5/5 3/3 +f 7/7 10/10 11/11 8/8 +f 11/11 12/12 9/9 8/8 +f 10/10 13/13 14/14 11/11 +f 14/14 15/15 12/12 11/11 +f 13/13 16/16 17/17 14/14 +f 17/17 18/18 15/15 14/14 +f 16/16 19/19 20/20 17/17 +f 20/20 21/21 18/18 17/17 +f 19/19 22/22 23/23 20/20 +f 23/23 24/24 21/21 20/20 +f 22/22 25/25 26/26 23/23 +f 26/26 27/27 24/24 23/23 +f 25/25 28/28 29/29 26/26 +f 29/29 30/30 27/27 26/26 +f 28/28 31/31 32/32 29/29 +f 32/32 33/33 30/30 29/29 +f 31/31 34/34 35/35 32/32 +f 35/35 36/36 33/33 32/32 +f 35/35 34/34 37/37 38/38 +f 39/39 36/36 35/35 38/38 +f 38/38 37/37 40/40 41/41 +f 42/42 39/39 38/38 41/41 +f 41/41 40/40 43/43 44/44 +f 45/45 42/42 41/41 44/44 +f 44/44 43/43 46/46 47/47 +f 48/48 45/45 44/44 47/47 +f 47/47 46/46 49/49 50/50 +f 51/51 48/48 47/47 50/50 +f 50/50 49/49 52/52 53/53 +f 54/54 51/51 50/50 53/53 +f 53/53 52/52 55/55 56/56 +f 57/57 54/54 53/53 56/56 +f 56/56 55/55 58/58 59/59 +f 60/60 57/57 56/56 59/59 +f 59/59 58/58 61/61 62/62 +f 63/63 60/60 59/59 62/62 +f 62/62 61/61 64/64 65/65 +f 66/66 63/63 62/62 65/65 +f 65/65 64/64 67/67 68/68 +f 69/69 66/66 65/65 68/68 +f 4/4 70/70 71/71 1/1 +f 72/72 70/70 4/4 6/6 +f 73/73 74/74 68/68 67/67 +f 68/68 74/74 75/75 69/69 +f 76/76 77/77 78/78 79/79 +f 80/80 81/81 76/76 79/79 +f 82/82 83/83 77/77 76/76 +f 81/81 84/84 82/82 76/76 +f 85/85 86/86 83/83 82/82 +f 84/84 87/87 85/85 82/82 +f 88/88 89/89 86/86 85/85 +f 87/87 90/90 88/88 85/85 +f 91/91 92/92 89/89 88/88 +f 90/90 93/93 91/91 88/88 +f 94/94 95/95 92/92 91/91 +f 93/93 96/96 94/94 91/91 +f 97/97 98/98 95/95 94/94 +f 96/96 99/99 97/97 94/94 +f 100/100 101/101 98/98 97/97 +f 99/99 102/102 100/100 97/97 +f 103/103 104/104 101/101 100/100 +f 102/102 105/105 103/103 100/100 +f 106/106 107/107 104/104 103/103 +f 105/105 108/108 106/106 103/103 +f 109/109 110/110 107/107 106/106 +f 108/108 111/111 109/109 106/106 +f 112/112 110/110 109/109 113/113 +f 109/109 111/111 114/114 113/113 +f 115/115 112/112 113/113 116/116 +f 113/113 114/114 117/117 116/116 +f 118/118 115/115 116/116 119/119 +f 116/116 117/117 120/120 119/119 +f 121/121 118/118 119/119 122/122 +f 119/119 120/120 123/123 122/122 +f 124/124 121/121 122/122 125/125 +f 122/122 123/123 126/126 125/125 +f 127/127 124/124 125/125 128/128 +f 125/125 126/126 129/129 128/128 +f 130/130 127/127 128/128 131/131 +f 128/128 129/129 132/132 131/131 +f 133/133 130/130 131/131 134/134 +f 131/131 132/132 135/135 134/134 +f 136/136 133/133 134/134 137/137 +f 134/134 135/135 138/138 137/137 +f 139/139 136/136 137/137 140/140 +f 137/137 138/138 141/141 140/140 +f 142/142 139/139 140/140 143/143 +f 140/140 141/141 144/144 143/143 +f 145/145 146/146 79/79 78/78 +f 79/79 146/146 147/147 80/80 +f 143/143 148/148 149/149 142/142 +f 150/150 148/148 143/143 144/144 +# 96 polygons From 47837c0e93869acfb5b14dcf7ace81f03e01e10e Mon Sep 17 00:00:00 2001 From: ffreyer Date: Mon, 18 Nov 2024 18:51:54 +0100 Subject: [PATCH 19/22] keep two sub-meshes in Sponza model --- test/runtests.jl | 12 +- test/testfiles/mini sponza/sponza.obj | 2908 +++++++++++++++++++++++++ 2 files changed, 2914 insertions(+), 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 5938b77..3ac5eb1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -191,17 +191,17 @@ end msh = load(joinpath(tf, "mini sponza/sponza.obj")) @test msh isa MetaMesh - @test length(faces(msh)) == 192 - @test length(coordinates(msh)) == 150 - @test length(texturecoordinates(msh)) == 150 - @test msh.views == [0x00000001:0x000000c0] + @test length(faces(msh)) == 1344 + @test length(coordinates(msh)) == 1236 + @test length(texturecoordinates(msh)) == 1236 + @test msh.views == [0x00000001:0x000000c0, 0x000000c1:0x00000540] @test test_face_indices(msh) # :groups, :material_names are in sync with views @test haskey(msh, :groups) - @test msh[:groups] == ["arcs_floor"] + @test msh[:groups] == ["arcs_floor", "arcs_03"] @test haskey(msh, :material_names) - @test msh[:material_names] == ["sp_00_luk_mali"] + @test msh[:material_names] == ["sp_00_luk_mali", "sp_00_luk_mali"] # :materials are all of them @test haskey(msh, :materials) diff --git a/test/testfiles/mini sponza/sponza.obj b/test/testfiles/mini sponza/sponza.obj index 982d541..8180dbd 100644 --- a/test/testfiles/mini sponza/sponza.obj +++ b/test/testfiles/mini sponza/sponza.obj @@ -407,3 +407,2911 @@ f 79/79 146/146 147/147 80/80 f 143/143 148/148 149/149 142/142 f 150/150 148/148 143/143 144/144 # 96 polygons + +# +# object arcs_03 +# + +v 10.847240 2.994934 2.523510 +v 10.847240 3.294398 2.430194 +v 10.835240 3.291739 2.423181 +v 10.835240 2.993140 2.516228 +v 10.835240 2.984763 2.482245 +v 10.835240 3.279327 2.390455 +v 10.847240 3.276668 2.383443 +v 10.847240 2.982969 2.474963 +v 10.875740 3.270817 2.368015 +v 10.875740 2.979020 2.458943 +v 10.913240 3.240676 2.288539 +v 10.913240 3.510025 2.167315 +v 10.927240 3.507237 2.162002 +v 10.927240 3.238548 2.282929 +v 10.835240 4.067590 1.913934 +v 10.835240 4.285757 1.695767 +v 10.847240 4.280143 1.690794 +v 10.847240 4.062617 1.908320 +v 10.835240 4.311954 1.718977 +v 10.835240 4.504839 1.472777 +v 10.827240 4.496610 1.467096 +v 10.827240 4.304469 1.712345 +v 10.827240 4.293242 1.702398 +v 10.827240 4.484265 1.458575 +v 10.835240 4.476035 1.452894 +v 10.847240 4.469863 1.448634 +v 10.903240 4.399498 1.400064 +v 10.903240 4.553304 1.145637 +v 10.913240 4.539137 1.138202 +v 10.913240 4.386330 1.390975 +v 10.927240 4.533824 1.135414 +v 10.927240 4.381392 1.387567 +v 10.903240 4.675321 0.874526 +v 10.913240 4.660361 0.868852 +v 10.927240 4.654751 0.866725 +v 10.847240 4.802016 0.922575 +v 10.847240 4.895332 0.623111 +v 10.835240 4.888051 0.621317 +v 10.835240 4.795003 0.919916 +v 10.835240 4.762278 0.907504 +v 10.835240 4.854067 0.612941 +v 10.847240 4.846786 0.611146 +v 10.847240 4.755265 0.904845 +v 10.875740 4.830765 0.607197 +v 10.875740 4.739837 0.898994 +v 10.835240 4.909682 0.309460 +v 10.847240 4.902237 0.308556 +v 10.875740 4.885858 0.306567 +v 10.847240 4.951872 0.314583 +v 10.847240 4.970811 0.001489 +v 10.835240 4.963311 0.001489 +v 10.835240 4.944427 0.313679 +v 10.835240 4.928311 0.001489 +v 10.847240 4.920811 0.001489 +v 10.847240 4.951872 -0.311605 +v 10.835240 4.944427 -0.310701 +v 10.835240 4.909682 -0.306482 +v 10.847240 4.902237 -0.305578 +v 10.835240 4.854067 -0.609962 +v 10.847240 4.846785 -0.608167 +v 10.875740 4.885858 -0.303589 +v 10.875740 4.830765 -0.604219 +v 10.835240 4.888050 -0.618338 +v 10.847240 4.895332 -0.620133 +v 10.847240 4.802015 -0.919597 +v 10.835240 4.795003 -0.916937 +v 10.835240 4.762277 -0.904526 +v 10.847240 4.755265 -0.901867 +v 10.875740 4.739837 -0.896016 +v 10.913240 4.660360 -0.865874 +v 10.903240 4.675321 -0.871548 +v 10.903240 4.553303 -1.142659 +v 10.913240 4.539136 -1.135224 +v 10.927240 4.654750 -0.863747 +v 10.927240 4.533823 -1.132435 +v 10.903240 4.399497 -1.397086 +v 10.913240 4.386329 -1.387997 +v 10.927240 4.381392 -1.384588 +v 10.827240 4.496609 -1.464118 +v 10.835240 4.504839 -1.469798 +v 10.835240 4.311954 -1.715998 +v 10.827240 4.304468 -1.709367 +v 10.835240 4.476034 -1.449916 +v 10.827240 4.484264 -1.455597 +v 10.827240 4.293241 -1.699420 +v 10.835240 4.285756 -1.692789 +v 10.847240 4.469862 -1.445655 +v 10.847240 4.280142 -1.687815 +v 10.835240 4.067590 -1.910955 +v 10.847240 4.062616 -1.905342 +v 10.927240 3.507236 -2.159023 +v 10.913240 3.510024 -2.164336 +v 10.913240 3.240675 -2.285560 +v 10.927240 3.238547 -2.279950 +v 10.835240 3.291738 -2.420202 +v 10.847240 3.294397 -2.427215 +v 10.847240 2.994934 -2.520531 +v 10.835240 2.993139 -2.513249 +v 10.847240 3.276667 -2.380464 +v 10.835240 3.279327 -2.387476 +v 10.835240 2.984763 -2.479266 +v 10.847240 2.982968 -2.471984 +v 10.875740 3.270816 -2.365036 +v 10.875740 2.979019 -2.455964 +v 10.847240 2.693312 2.528045 +v 10.835240 2.693312 2.535655 +v 10.835240 2.693311 -2.532676 +v 10.847240 2.693311 -2.525066 +v -10.820760 3.291739 2.423181 +v -10.832760 3.294398 2.430194 +v -10.832760 2.994934 2.523510 +v -10.820760 2.993140 2.516228 +v -10.832760 3.276668 2.383443 +v -10.820760 3.279327 2.390455 +v -10.820760 2.984763 2.482245 +v -10.832760 2.982969 2.474963 +v -10.861259 3.270817 2.368015 +v -10.861259 2.979020 2.458943 +v -10.912760 3.507237 2.162002 +v -10.898760 3.510025 2.167315 +v -10.898760 3.240676 2.288539 +v -10.912760 3.238548 2.282929 +v -10.832760 4.280143 1.690794 +v -10.820760 4.285757 1.695767 +v -10.820760 4.067590 1.913934 +v -10.832760 4.062617 1.908320 +v -10.812759 4.496610 1.467096 +v -10.820760 4.504839 1.472777 +v -10.820760 4.311954 1.718977 +v -10.812759 4.304469 1.712345 +v -10.820760 4.476035 1.452894 +v -10.812759 4.484265 1.458575 +v -10.812759 4.293242 1.702398 +v -10.832760 4.469863 1.448634 +v -10.898760 4.539137 1.138202 +v -10.888760 4.553304 1.145637 +v -10.888760 4.399498 1.400064 +v -10.898760 4.386330 1.390975 +v -10.912760 4.533824 1.135414 +v -10.912760 4.381392 1.387567 +v -10.898760 4.660361 0.868852 +v -10.888760 4.675321 0.874526 +v -10.912760 4.654751 0.866725 +v -10.820760 4.888051 0.621317 +v -10.832760 4.895332 0.623111 +v -10.832760 4.802016 0.922575 +v -10.820760 4.795003 0.919916 +v -10.832760 4.846786 0.611146 +v -10.820760 4.854067 0.612941 +v -10.820760 4.762278 0.907504 +v -10.832760 4.755265 0.904845 +v -10.861259 4.830765 0.607197 +v -10.861259 4.739837 0.898994 +v -10.832760 4.902237 0.308556 +v -10.820760 4.909682 0.309460 +v -10.861259 4.885858 0.306567 +v -10.820760 4.963311 0.001489 +v -10.832760 4.970811 0.001489 +v -10.832760 4.951872 0.314583 +v -10.820760 4.944427 0.313679 +v -10.832760 4.920811 0.001489 +v -10.820760 4.928311 0.001489 +v -10.832760 4.951872 -0.311605 +v -10.820760 4.944427 -0.310701 +v -10.820760 4.909682 -0.306482 +v -10.832760 4.902237 -0.305578 +v -10.820760 4.854067 -0.609962 +v -10.832760 4.846785 -0.608167 +v -10.861259 4.885858 -0.303589 +v -10.861259 4.830765 -0.604219 +v -10.832760 4.802015 -0.919597 +v -10.832760 4.895332 -0.620133 +v -10.820760 4.888050 -0.618338 +v -10.820760 4.795003 -0.916937 +v -10.820760 4.762277 -0.904526 +v -10.832760 4.755265 -0.901867 +v -10.861259 4.739837 -0.896016 +v -10.888760 4.553303 -1.142659 +v -10.888760 4.675321 -0.871548 +v -10.898760 4.660360 -0.865874 +v -10.898760 4.539136 -1.135224 +v -10.912760 4.654750 -0.863747 +v -10.912760 4.533823 -1.132435 +v -10.888760 4.399497 -1.397086 +v -10.898760 4.386329 -1.387997 +v -10.912760 4.381392 -1.384588 +v -10.820760 4.311954 -1.715998 +v -10.820760 4.504839 -1.469798 +v -10.812759 4.496609 -1.464118 +v -10.812759 4.304468 -1.709367 +v -10.812759 4.293241 -1.699420 +v -10.812759 4.484264 -1.455597 +v -10.820760 4.476034 -1.449916 +v -10.820760 4.285756 -1.692789 +v -10.832760 4.469862 -1.445655 +v -10.832760 4.280142 -1.687815 +v -10.820760 4.067590 -1.910955 +v -10.832760 4.062616 -1.905342 +v -10.898760 3.240675 -2.285560 +v -10.898760 3.510024 -2.164336 +v -10.912760 3.507236 -2.159023 +v -10.912760 3.238547 -2.279950 +v -10.832760 2.994934 -2.520531 +v -10.832760 3.294397 -2.427215 +v -10.820760 3.291738 -2.420202 +v -10.820760 2.993139 -2.513249 +v -10.820760 2.984763 -2.479266 +v -10.820760 3.279327 -2.387476 +v -10.832760 3.276667 -2.380464 +v -10.832760 2.982968 -2.471984 +v -10.861259 3.270816 -2.365036 +v -10.861259 2.979019 -2.455964 +v -10.820760 2.693312 2.535655 +v -10.832760 2.693312 2.528045 +v -10.832760 2.693311 -2.525066 +v -10.820760 2.693311 -2.532676 +v 10.927240 2.995533 2.525938 +v 10.927240 3.295285 2.432531 +v 10.827240 3.288193 2.413831 +v 10.827240 2.990746 2.506519 +v 10.827240 3.282873 2.399806 +v 10.827240 2.987157 2.491955 +v 10.894240 3.262129 2.345107 +v 10.894240 2.973157 2.435154 +v 10.899740 3.250959 2.315654 +v 10.899740 2.965618 2.404570 +v 10.903240 3.246349 2.303499 +v 10.903240 2.962507 2.391948 +v 10.913240 2.958678 2.376413 +v 10.927240 2.957242 2.370587 +v 10.927240 3.581592 2.303674 +v 10.847240 3.580431 2.301461 +v 10.835240 3.576945 2.294820 +v 10.827240 3.572298 2.285965 +v 10.827240 3.565327 2.272683 +v 10.835240 3.560680 2.263829 +v 10.847240 3.557194 2.257188 +v 10.875740 3.549526 2.242578 +v 10.894240 3.538141 2.220884 +v 10.899740 3.523502 2.192992 +v 10.903240 3.517460 2.181482 +v 10.927240 3.850280 2.141247 +v 10.847240 3.848860 2.139189 +v 10.835240 3.844599 2.133017 +v 10.827240 3.838919 2.124787 +v 10.827240 3.830398 2.112442 +v 10.835240 3.824717 2.104212 +v 10.847240 3.820457 2.098040 +v 10.875740 3.811084 2.084461 +v 10.894240 3.797166 2.064298 +v 10.899740 3.779272 2.038374 +v 10.903240 3.771887 2.027675 +v 10.913240 3.762798 2.014508 +v 10.927240 3.759390 2.009570 +v 10.927240 4.097431 1.947617 +v 10.847240 4.095772 1.945745 +v 10.835240 4.090799 1.940132 +v 10.827240 4.084168 1.932647 +v 10.827240 4.074221 1.921419 +v 10.875740 4.051675 1.895970 +v 10.894240 4.035429 1.877631 +v 10.899740 4.014540 1.854053 +v 10.903240 4.005919 1.844322 +v 10.913240 3.995310 1.832346 +v 10.927240 3.991331 1.827855 +v 10.927240 4.319440 1.725608 +v 10.847240 4.317568 1.723950 +v 10.875740 4.267792 1.679852 +v 10.894240 4.249454 1.663606 +v 10.899740 4.225875 1.642717 +v 10.903240 4.216145 1.634097 +v 10.913240 4.204169 1.623487 +v 10.927240 4.199678 1.619508 +v 10.927240 4.513069 1.478457 +v 10.847240 4.511012 1.477037 +v 10.875740 4.456284 1.439261 +v 10.894240 4.436120 1.425343 +v 10.899740 4.410196 1.407449 +v 10.927240 4.675497 1.209769 +v 10.847240 4.673283 1.208607 +v 10.835240 4.666642 1.205122 +v 10.827240 4.657788 1.200475 +v 10.827240 4.644506 1.193504 +v 10.835240 4.635651 1.188857 +v 10.847240 4.629010 1.185371 +v 10.875740 4.614400 1.177703 +v 10.894240 4.592707 1.166317 +v 10.899740 4.564815 1.151679 +v 10.927240 4.804354 0.923462 +v 10.827240 4.785653 0.916369 +v 10.827240 4.771628 0.911050 +v 10.894240 4.716929 0.890306 +v 10.899740 4.687476 0.879136 +v 10.927240 4.897760 0.623710 +v 10.827240 4.878341 0.618923 +v 10.827240 4.863777 0.615334 +v 10.894240 4.806977 0.601334 +v 10.899740 4.776392 0.593795 +v 10.903240 4.763770 0.590684 +v 10.913240 4.748235 0.586855 +v 10.927240 4.742409 0.585419 +v 10.927240 4.954354 0.314884 +v 10.827240 4.934500 0.312474 +v 10.827240 4.919610 0.310666 +v 10.894240 4.861536 0.303614 +v 10.899740 4.830266 0.299817 +v 10.903240 4.817360 0.298250 +v 10.913240 4.801477 0.296322 +v 10.927240 4.795521 0.295599 +v 10.927240 4.973311 0.001489 +v 10.827240 4.953311 0.001489 +v 10.827240 4.938311 0.001489 +v 10.875740 4.904311 0.001489 +v 10.894240 4.879811 0.001489 +v 10.899740 4.848311 0.001489 +v 10.903240 4.835311 0.001489 +v 10.913240 4.819311 0.001489 +v 10.927240 4.813311 0.001489 +v 10.927240 4.954354 -0.311906 +v 10.827240 4.934500 -0.309495 +v 10.827240 4.919610 -0.307687 +v 10.894240 4.861536 -0.300636 +v 10.899740 4.830266 -0.296839 +v 10.903240 4.817360 -0.295272 +v 10.913240 4.801477 -0.293344 +v 10.927240 4.795521 -0.292620 +v 10.927240 4.897759 -0.620731 +v 10.827240 4.878341 -0.615945 +v 10.827240 4.863777 -0.612355 +v 10.894240 4.806977 -0.598355 +v 10.899740 4.776392 -0.590817 +v 10.903240 4.763770 -0.587706 +v 10.913240 4.748235 -0.583877 +v 10.927240 4.742409 -0.582441 +v 10.927240 4.804353 -0.920483 +v 10.827240 4.785653 -0.913391 +v 10.827240 4.771627 -0.908072 +v 10.894240 4.716928 -0.887328 +v 10.899740 4.687476 -0.876158 +v 10.927240 4.675497 -1.206791 +v 10.847240 4.673282 -1.205629 +v 10.835240 4.666642 -1.202144 +v 10.827240 4.657787 -1.197496 +v 10.827240 4.644506 -1.190526 +v 10.835240 4.635651 -1.185878 +v 10.847240 4.629010 -1.182393 +v 10.875740 4.614400 -1.174725 +v 10.894240 4.592706 -1.163339 +v 10.899740 4.564814 -1.148700 +v 10.927240 4.513069 -1.475479 +v 10.847240 4.511011 -1.474059 +v 10.875740 4.456283 -1.436282 +v 10.894240 4.436120 -1.422365 +v 10.899740 4.410196 -1.404471 +v 10.927240 4.319439 -1.722629 +v 10.847240 4.317567 -1.720971 +v 10.875740 4.267791 -1.676874 +v 10.894240 4.249453 -1.660627 +v 10.899740 4.225874 -1.639739 +v 10.903240 4.216144 -1.631118 +v 10.913240 4.204168 -1.620508 +v 10.927240 4.199677 -1.616530 +v 10.927240 4.097430 -1.944638 +v 10.847240 4.095771 -1.942767 +v 10.835240 4.090799 -1.937153 +v 10.827240 4.084167 -1.929668 +v 10.827240 4.074221 -1.918440 +v 10.875740 4.051675 -1.892991 +v 10.894240 4.035429 -1.874652 +v 10.899740 4.014540 -1.851074 +v 10.903240 4.005919 -1.841344 +v 10.913240 3.995309 -1.829368 +v 10.927240 3.991331 -1.824877 +v 10.927240 3.850279 -2.138268 +v 10.847240 3.848859 -2.136211 +v 10.835240 3.844599 -2.130038 +v 10.827240 3.838918 -2.121809 +v 10.827240 3.830397 -2.109464 +v 10.835240 3.824717 -2.101234 +v 10.847240 3.820456 -2.095062 +v 10.875740 3.811083 -2.081482 +v 10.894240 3.797165 -2.061319 +v 10.899740 3.779271 -2.035395 +v 10.903240 3.771886 -2.024696 +v 10.913240 3.762798 -2.011529 +v 10.927240 3.759389 -2.006591 +v 10.927240 3.581592 -2.300696 +v 10.847240 3.580430 -2.298482 +v 10.835240 3.576944 -2.291841 +v 10.827240 3.572297 -2.282987 +v 10.827240 3.565326 -2.269705 +v 10.835240 3.560679 -2.260850 +v 10.847240 3.557194 -2.254210 +v 10.875740 3.549526 -2.239599 +v 10.894240 3.538140 -2.217906 +v 10.899740 3.523501 -2.190014 +v 10.903240 3.517460 -2.178503 +v 10.927240 3.295284 -2.429552 +v 10.827240 3.288192 -2.410852 +v 10.827240 3.282873 -2.396827 +v 10.894240 3.262128 -2.342128 +v 10.899740 3.250958 -2.312675 +v 10.903240 3.246349 -2.300520 +v 10.927240 2.995532 -2.522959 +v 10.827240 2.990746 -2.503540 +v 10.827240 2.987156 -2.488976 +v 10.894240 2.973156 -2.432175 +v 10.899740 2.965618 -2.401591 +v 10.903240 2.962507 -2.388968 +v 10.913240 2.958678 -2.373434 +v 10.927240 2.957242 -2.367608 +v 10.847240 2.693312 2.578785 +v 10.927240 2.693312 2.581322 +v 10.835240 2.693312 2.571174 +v 10.827240 2.693312 2.561026 +v 10.827240 2.693312 2.545804 +v 10.875740 2.693312 2.511301 +v 10.894240 2.693312 2.486438 +v 10.899740 2.693312 2.454472 +v 10.903240 2.693312 2.441279 +v 10.913240 2.693312 2.425043 +v 10.927240 2.693312 2.418954 +v 10.927240 2.693311 -2.578343 +v 10.847240 2.693311 -2.575806 +v 10.835240 2.693311 -2.568195 +v 10.827240 2.693311 -2.558047 +v 10.827240 2.693311 -2.542825 +v 10.875740 2.693311 -2.508322 +v 10.894240 2.693311 -2.483459 +v 10.899740 2.693311 -2.451493 +v 10.903240 2.693311 -2.438300 +v 10.913240 2.693311 -2.422064 +v 10.927240 2.693311 -2.415975 +v -10.912760 3.295285 2.432531 +v -10.912760 2.995533 2.525938 +v -10.812759 3.288193 2.413831 +v -10.812759 2.990746 2.506519 +v -10.812759 3.282873 2.399806 +v -10.812759 2.987157 2.491955 +v -10.879760 3.262129 2.345107 +v -10.879760 2.973157 2.435154 +v -10.885260 3.250959 2.315654 +v -10.885260 2.965618 2.404570 +v -10.888760 3.246349 2.303499 +v -10.888760 2.962507 2.391948 +v -10.898760 2.958678 2.376413 +v -10.912760 2.957242 2.370587 +v -10.832760 3.580431 2.301461 +v -10.912760 3.581592 2.303674 +v -10.820760 3.576945 2.294820 +v -10.812759 3.572298 2.285965 +v -10.812759 3.565327 2.272683 +v -10.820760 3.560680 2.263829 +v -10.832760 3.557194 2.257188 +v -10.861259 3.549526 2.242578 +v -10.879760 3.538141 2.220884 +v -10.885260 3.523502 2.192992 +v -10.888760 3.517460 2.181482 +v -10.832760 3.848860 2.139189 +v -10.912760 3.850280 2.141247 +v -10.820760 3.844599 2.133017 +v -10.812759 3.838919 2.124787 +v -10.812759 3.830398 2.112442 +v -10.820760 3.824717 2.104212 +v -10.832760 3.820457 2.098040 +v -10.861259 3.811084 2.084461 +v -10.879760 3.797166 2.064298 +v -10.885260 3.779272 2.038374 +v -10.888760 3.771887 2.027675 +v -10.898760 3.762798 2.014508 +v -10.912760 3.759390 2.009570 +v -10.832760 4.095772 1.945745 +v -10.912760 4.097431 1.947617 +v -10.820760 4.090799 1.940132 +v -10.812759 4.084168 1.932647 +v -10.812759 4.074221 1.921419 +v -10.861259 4.051675 1.895970 +v -10.879760 4.035429 1.877631 +v -10.885260 4.014540 1.854053 +v -10.888760 4.005919 1.844322 +v -10.898760 3.995310 1.832346 +v -10.912760 3.991331 1.827855 +v -10.832760 4.317568 1.723950 +v -10.912760 4.319440 1.725608 +v -10.861259 4.267792 1.679852 +v -10.879760 4.249454 1.663606 +v -10.885260 4.225875 1.642717 +v -10.888760 4.216145 1.634097 +v -10.898760 4.204169 1.623487 +v -10.912760 4.199678 1.619508 +v -10.832760 4.511012 1.477037 +v -10.912760 4.513069 1.478457 +v -10.861259 4.456284 1.439261 +v -10.879760 4.436120 1.425343 +v -10.885260 4.410196 1.407449 +v -10.832760 4.673283 1.208607 +v -10.912760 4.675497 1.209769 +v -10.820760 4.666642 1.205122 +v -10.812759 4.657788 1.200475 +v -10.812759 4.644506 1.193504 +v -10.820760 4.635651 1.188857 +v -10.832760 4.629010 1.185371 +v -10.861259 4.614400 1.177703 +v -10.879760 4.592707 1.166317 +v -10.885260 4.564815 1.151679 +v -10.912760 4.804354 0.923462 +v -10.812759 4.785653 0.916369 +v -10.812759 4.771628 0.911050 +v -10.879760 4.716929 0.890306 +v -10.885260 4.687476 0.879136 +v -10.912760 4.897760 0.623710 +v -10.812759 4.878341 0.618923 +v -10.812759 4.863777 0.615334 +v -10.879760 4.806977 0.601334 +v -10.885260 4.776392 0.593795 +v -10.888760 4.763770 0.590684 +v -10.898760 4.748235 0.586855 +v -10.912760 4.742409 0.585419 +v -10.912760 4.954354 0.314884 +v -10.812759 4.934500 0.312474 +v -10.812759 4.919610 0.310666 +v -10.879760 4.861536 0.303614 +v -10.885260 4.830266 0.299817 +v -10.888760 4.817360 0.298250 +v -10.898760 4.801477 0.296322 +v -10.912760 4.795521 0.295599 +v -10.912760 4.973311 0.001489 +v -10.812759 4.953311 0.001489 +v -10.812759 4.938311 0.001489 +v -10.861259 4.904311 0.001489 +v -10.879760 4.879811 0.001489 +v -10.885260 4.848311 0.001489 +v -10.888760 4.835311 0.001489 +v -10.898760 4.819311 0.001489 +v -10.912760 4.813311 0.001489 +v -10.912760 4.954354 -0.311906 +v -10.812759 4.934500 -0.309495 +v -10.812759 4.919610 -0.307687 +v -10.879760 4.861536 -0.300636 +v -10.885260 4.830266 -0.296839 +v -10.888760 4.817360 -0.295272 +v -10.898760 4.801477 -0.293344 +v -10.912760 4.795521 -0.292620 +v -10.912760 4.897759 -0.620731 +v -10.812759 4.878341 -0.615945 +v -10.812759 4.863777 -0.612355 +v -10.879760 4.806977 -0.598355 +v -10.885260 4.776392 -0.590817 +v -10.888760 4.763770 -0.587706 +v -10.898760 4.748235 -0.583877 +v -10.912760 4.742409 -0.582441 +v -10.912760 4.804353 -0.920483 +v -10.812759 4.785653 -0.913391 +v -10.812759 4.771627 -0.908072 +v -10.879760 4.716928 -0.887328 +v -10.885260 4.687476 -0.876158 +v -10.912760 4.675497 -1.206791 +v -10.832760 4.673282 -1.205629 +v -10.820760 4.666642 -1.202144 +v -10.812759 4.657787 -1.197496 +v -10.812759 4.644506 -1.190526 +v -10.820760 4.635651 -1.185878 +v -10.832760 4.629010 -1.182393 +v -10.861259 4.614400 -1.174725 +v -10.879760 4.592706 -1.163339 +v -10.885260 4.564814 -1.148700 +v -10.912760 4.513069 -1.475479 +v -10.832760 4.511011 -1.474059 +v -10.861259 4.456283 -1.436282 +v -10.879760 4.436120 -1.422365 +v -10.885260 4.410196 -1.404471 +v -10.912760 4.319439 -1.722629 +v -10.832760 4.317567 -1.720971 +v -10.861259 4.267791 -1.676874 +v -10.879760 4.249453 -1.660627 +v -10.885260 4.225874 -1.639739 +v -10.888760 4.216144 -1.631118 +v -10.898760 4.204168 -1.620508 +v -10.912760 4.199677 -1.616530 +v -10.912760 4.097430 -1.944638 +v -10.832760 4.095771 -1.942767 +v -10.820760 4.090799 -1.937153 +v -10.812759 4.084167 -1.929668 +v -10.812759 4.074221 -1.918440 +v -10.861259 4.051675 -1.892991 +v -10.879760 4.035429 -1.874652 +v -10.885260 4.014540 -1.851074 +v -10.888760 4.005919 -1.841344 +v -10.898760 3.995309 -1.829368 +v -10.912760 3.991331 -1.824877 +v -10.912760 3.850279 -2.138268 +v -10.832760 3.848859 -2.136211 +v -10.820760 3.844599 -2.130038 +v -10.812759 3.838918 -2.121809 +v -10.812759 3.830397 -2.109464 +v -10.820760 3.824717 -2.101234 +v -10.832760 3.820456 -2.095062 +v -10.861259 3.811083 -2.081482 +v -10.879760 3.797165 -2.061319 +v -10.885260 3.779271 -2.035395 +v -10.888760 3.771886 -2.024696 +v -10.898760 3.762798 -2.011529 +v -10.912760 3.759389 -2.006591 +v -10.912760 3.581592 -2.300696 +v -10.832760 3.580430 -2.298482 +v -10.820760 3.576944 -2.291841 +v -10.812759 3.572297 -2.282987 +v -10.812759 3.565326 -2.269705 +v -10.820760 3.560679 -2.260850 +v -10.832760 3.557194 -2.254210 +v -10.861259 3.549526 -2.239599 +v -10.879760 3.538140 -2.217906 +v -10.885260 3.523501 -2.190014 +v -10.888760 3.517460 -2.178503 +v -10.912760 3.295284 -2.429552 +v -10.812759 3.288192 -2.410852 +v -10.812759 3.282873 -2.396827 +v -10.879760 3.262128 -2.342128 +v -10.885260 3.250958 -2.312675 +v -10.888760 3.246349 -2.300520 +v -10.912760 2.995532 -2.522959 +v -10.812759 2.990746 -2.503540 +v -10.812759 2.987156 -2.488976 +v -10.879760 2.973156 -2.432175 +v -10.885260 2.965618 -2.401591 +v -10.888760 2.962507 -2.388968 +v -10.898760 2.958678 -2.373434 +v -10.912760 2.957242 -2.367608 +v -10.912760 2.693312 2.581322 +v -10.832760 2.693312 2.578785 +v -10.820760 2.693312 2.571174 +v -10.812759 2.693312 2.561026 +v -10.812759 2.693312 2.545804 +v -10.861259 2.693312 2.511301 +v -10.879760 2.693312 2.486438 +v -10.885260 2.693312 2.454472 +v -10.888760 2.693312 2.441279 +v -10.898760 2.693312 2.425043 +v -10.912760 2.693312 2.418954 +v -10.832760 2.693311 -2.575806 +v -10.912760 2.693311 -2.578343 +v -10.820760 2.693311 -2.568195 +v -10.812759 2.693311 -2.558047 +v -10.812759 2.693311 -2.542825 +v -10.861259 2.693311 -2.508322 +v -10.879760 2.693311 -2.483459 +v -10.885260 2.693311 -2.451493 +v -10.888760 2.693311 -2.438300 +v -10.898760 2.693311 -2.422064 +v -10.912760 2.693311 -2.415975 +v 10.847240 2.982969 2.474963 +v 10.847240 3.276668 2.383443 +v 10.847240 2.982969 2.474963 +v 10.847240 4.755265 0.904845 +v 10.847240 4.846786 0.611146 +v 10.847240 4.755265 0.904845 +v 10.847240 4.846786 0.611146 +v 10.847240 4.902237 0.308556 +v 10.847240 4.846786 0.611146 +v 10.847240 4.902237 -0.305578 +v 10.847240 4.846785 -0.608167 +v 10.847240 4.846785 -0.608167 +v 10.847240 4.846785 -0.608167 +v 10.847240 4.755265 -0.901867 +v 10.847240 4.755265 -0.901867 +v 10.847240 3.276667 -2.380464 +v 10.847240 2.982968 -2.471984 +v 10.847240 2.982968 -2.471984 +v -10.832760 3.276668 2.383443 +v -10.832760 2.982969 2.474963 +v -10.832760 2.982969 2.474963 +v -10.832760 4.846786 0.611146 +v -10.832760 4.755265 0.904845 +v -10.832760 4.755265 0.904845 +v -10.832760 4.902237 0.308556 +v -10.832760 4.846786 0.611146 +v -10.832760 4.846786 0.611146 +v -10.832760 4.846785 -0.608167 +v -10.832760 4.902237 -0.305578 +v -10.832760 4.846785 -0.608167 +v -10.832760 4.755265 -0.901867 +v -10.832760 4.846785 -0.608167 +v -10.832760 4.755265 -0.901867 +v -10.832760 2.982968 -2.471984 +v -10.832760 3.276667 -2.380464 +v -10.832760 2.982968 -2.471984 +v 10.847240 3.294398 2.430194 +v 10.847240 3.294398 2.430194 +v 10.847240 2.994934 2.523510 +v 10.899740 2.965618 2.404570 +v 10.899740 3.250959 2.315654 +v 10.899740 2.965618 2.404570 +v 10.847240 3.294398 2.430194 +v 10.847240 3.580431 2.301461 +v 10.847240 3.276668 2.383443 +v 10.847240 3.557194 2.257188 +v 10.847240 3.276668 2.383443 +v 10.899740 3.250959 2.315654 +v 10.899740 3.523502 2.192992 +v 10.899740 3.250959 2.315654 +v 10.847240 3.580431 2.301461 +v 10.847240 3.848860 2.139189 +v 10.847240 3.580431 2.301461 +v 10.847240 3.557194 2.257188 +v 10.847240 3.820457 2.098040 +v 10.847240 3.557194 2.257188 +v 10.899740 3.523502 2.192992 +v 10.899740 3.779272 2.038374 +v 10.899740 3.523502 2.192992 +v 10.847240 3.848860 2.139189 +v 10.847240 4.095772 1.945745 +v 10.847240 3.848860 2.139189 +v 10.847240 3.820457 2.098040 +v 10.847240 4.062617 1.908320 +v 10.847240 3.820457 2.098040 +v 10.899740 3.779272 2.038374 +v 10.899740 4.014540 1.854053 +v 10.899740 3.779272 2.038374 +v 10.847240 4.095772 1.945745 +v 10.847240 4.317568 1.723950 +v 10.847240 4.095772 1.945745 +v 10.847240 4.062617 1.908320 +v 10.847240 4.280143 1.690794 +v 10.847240 4.062617 1.908320 +v 10.899740 4.014540 1.854053 +v 10.899740 4.225875 1.642717 +v 10.899740 4.014540 1.854053 +v 10.847240 4.317568 1.723950 +v 10.847240 4.511012 1.477037 +v 10.847240 4.317568 1.723950 +v 10.847240 4.280143 1.690794 +v 10.847240 4.469863 1.448634 +v 10.847240 4.280143 1.690794 +v 10.899740 4.225875 1.642717 +v 10.899740 4.410196 1.407449 +v 10.899740 4.225875 1.642717 +v 10.847240 4.511012 1.477037 +v 10.847240 4.673283 1.208607 +v 10.847240 4.511012 1.477037 +v 10.847240 4.469863 1.448634 +v 10.847240 4.629010 1.185371 +v 10.847240 4.469863 1.448634 +v 10.899740 4.410196 1.407449 +v 10.899740 4.564815 1.151679 +v 10.899740 4.410196 1.407449 +v 10.847240 4.802016 0.922575 +v 10.847240 4.802016 0.922575 +v 10.847240 4.673283 1.208607 +v 10.847240 4.673283 1.208607 +v 10.847240 4.629010 1.185371 +v 10.847240 4.755265 0.904845 +v 10.847240 4.629010 1.185371 +v 10.899740 4.564815 1.151679 +v 10.899740 4.687476 0.879136 +v 10.899740 4.564815 1.151679 +v 10.847240 4.895332 0.623111 +v 10.847240 4.895332 0.623111 +v 10.847240 4.802016 0.922575 +v 10.899740 4.687476 0.879136 +v 10.899740 4.776392 0.593795 +v 10.899740 4.687476 0.879136 +v 10.847240 4.951872 0.314583 +v 10.847240 4.951872 0.314583 +v 10.847240 4.895332 0.623111 +v 10.899740 4.776392 0.593795 +v 10.899740 4.830266 0.299817 +v 10.899740 4.776392 0.593795 +v 10.847240 4.970811 0.001489 +v 10.847240 4.970811 0.001489 +v 10.847240 4.951872 0.314583 +v 10.847240 4.902237 0.308556 +v 10.847240 4.920811 0.001489 +v 10.847240 4.902237 0.308556 +v 10.899740 4.830266 0.299817 +v 10.899740 4.848311 0.001489 +v 10.899740 4.830266 0.299817 +v 10.847240 4.970811 0.001489 +v 10.847240 4.951872 -0.311605 +v 10.847240 4.970811 0.001489 +v 10.847240 4.920811 0.001489 +v 10.847240 4.902237 -0.305578 +v 10.847240 4.902237 -0.305578 +v 10.899740 4.848311 0.001489 +v 10.899740 4.830266 -0.296839 +v 10.899740 4.830266 -0.296839 +v 10.847240 4.951872 -0.311605 +v 10.847240 4.895332 -0.620133 +v 10.847240 4.951872 -0.311605 +v 10.899740 4.830266 -0.296839 +v 10.899740 4.776392 -0.590817 +v 10.899740 4.776392 -0.590817 +v 10.847240 4.895332 -0.620133 +v 10.847240 4.802015 -0.919597 +v 10.847240 4.895332 -0.620133 +v 10.899740 4.776392 -0.590817 +v 10.899740 4.687476 -0.876158 +v 10.899740 4.687476 -0.876158 +v 10.847240 4.802015 -0.919597 +v 10.847240 4.802015 -0.919597 +v 10.847240 4.673282 -1.205629 +v 10.847240 4.673282 -1.205629 +v 10.847240 4.755265 -0.901867 +v 10.847240 4.629010 -1.182393 +v 10.847240 4.629010 -1.182393 +v 10.899740 4.687476 -0.876158 +v 10.899740 4.564814 -1.148700 +v 10.899740 4.564814 -1.148700 +v 10.847240 4.673282 -1.205629 +v 10.847240 4.511011 -1.474059 +v 10.847240 4.511011 -1.474059 +v 10.847240 4.629010 -1.182393 +v 10.847240 4.469862 -1.445655 +v 10.847240 4.469862 -1.445655 +v 10.899740 4.564814 -1.148700 +v 10.899740 4.410196 -1.404471 +v 10.899740 4.410196 -1.404471 +v 10.847240 4.511011 -1.474059 +v 10.847240 4.317567 -1.720971 +v 10.847240 4.317567 -1.720971 +v 10.847240 4.469862 -1.445655 +v 10.847240 4.280142 -1.687815 +v 10.847240 4.280142 -1.687815 +v 10.899740 4.410196 -1.404471 +v 10.899740 4.225874 -1.639739 +v 10.899740 4.225874 -1.639739 +v 10.847240 4.317567 -1.720971 +v 10.847240 4.095771 -1.942767 +v 10.847240 4.095771 -1.942767 +v 10.847240 4.280142 -1.687815 +v 10.847240 4.062616 -1.905342 +v 10.847240 4.062616 -1.905342 +v 10.899740 4.225874 -1.639739 +v 10.899740 4.014540 -1.851074 +v 10.899740 4.014540 -1.851074 +v 10.847240 4.095771 -1.942767 +v 10.847240 3.848859 -2.136211 +v 10.847240 3.848859 -2.136211 +v 10.847240 4.062616 -1.905342 +v 10.847240 3.820456 -2.095062 +v 10.847240 3.820456 -2.095062 +v 10.899740 4.014540 -1.851074 +v 10.899740 3.779271 -2.035395 +v 10.899740 3.779271 -2.035395 +v 10.847240 3.848859 -2.136211 +v 10.847240 3.580430 -2.298482 +v 10.847240 3.580430 -2.298482 +v 10.847240 3.820456 -2.095062 +v 10.847240 3.557194 -2.254210 +v 10.847240 3.557194 -2.254210 +v 10.899740 3.779271 -2.035395 +v 10.899740 3.523501 -2.190014 +v 10.899740 3.523501 -2.190014 +v 10.847240 3.294397 -2.427215 +v 10.847240 3.580430 -2.298482 +v 10.847240 3.557194 -2.254210 +v 10.847240 3.276667 -2.380464 +v 10.847240 3.276667 -2.380464 +v 10.899740 3.523501 -2.190014 +v 10.899740 3.250958 -2.312675 +v 10.899740 3.250958 -2.312675 +v 10.847240 3.294397 -2.427215 +v 10.847240 2.994934 -2.520531 +v 10.847240 3.294397 -2.427215 +v 10.899740 3.250958 -2.312675 +v 10.899740 2.965618 -2.401591 +v 10.899740 2.965618 -2.401591 +v 10.847240 2.994934 2.523510 +v 10.847240 2.994934 2.523510 +v 10.847240 2.693312 2.578785 +v 10.847240 2.693312 2.578785 +v 10.847240 2.693312 2.528045 +v 10.847240 2.693312 2.528045 +v 10.847240 2.982969 2.474963 +v 10.899740 2.693312 2.454472 +v 10.899740 2.693312 2.454472 +v 10.899740 2.965618 2.404570 +v 10.847240 2.994934 -2.520531 +v 10.847240 2.994934 -2.520531 +v 10.847240 2.693311 -2.575806 +v 10.847240 2.693311 -2.575806 +v 10.847240 2.693311 -2.525066 +v 10.847240 2.982968 -2.471984 +v 10.847240 2.693311 -2.525066 +v 10.899740 2.693311 -2.451493 +v 10.899740 2.965618 -2.401591 +v 10.899740 2.693311 -2.451493 +v -10.832760 3.294398 2.430194 +v -10.832760 2.994934 2.523510 +v -10.832760 3.294398 2.430194 +v -10.885260 3.250959 2.315654 +v -10.885260 2.965618 2.404570 +v -10.885260 2.965618 2.404570 +v -10.832760 3.294398 2.430194 +v -10.832760 3.580431 2.301461 +v -10.832760 3.557194 2.257188 +v -10.832760 3.276668 2.383443 +v -10.832760 3.276668 2.383443 +v -10.885260 3.523502 2.192992 +v -10.885260 3.250959 2.315654 +v -10.885260 3.250959 2.315654 +v -10.832760 3.848860 2.139189 +v -10.832760 3.580431 2.301461 +v -10.832760 3.580431 2.301461 +v -10.832760 3.820457 2.098040 +v -10.832760 3.557194 2.257188 +v -10.832760 3.557194 2.257188 +v -10.885260 3.779272 2.038374 +v -10.885260 3.523502 2.192992 +v -10.885260 3.523502 2.192992 +v -10.832760 4.095772 1.945745 +v -10.832760 3.848860 2.139189 +v -10.832760 3.848860 2.139189 +v -10.832760 4.062617 1.908320 +v -10.832760 3.820457 2.098040 +v -10.832760 3.820457 2.098040 +v -10.885260 4.014540 1.854053 +v -10.885260 3.779272 2.038374 +v -10.885260 3.779272 2.038374 +v -10.832760 4.317568 1.723950 +v -10.832760 4.095772 1.945745 +v -10.832760 4.095772 1.945745 +v -10.832760 4.280143 1.690794 +v -10.832760 4.062617 1.908320 +v -10.832760 4.062617 1.908320 +v -10.885260 4.225875 1.642717 +v -10.885260 4.014540 1.854053 +v -10.885260 4.014540 1.854053 +v -10.832760 4.511012 1.477037 +v -10.832760 4.317568 1.723950 +v -10.832760 4.317568 1.723950 +v -10.832760 4.469863 1.448634 +v -10.832760 4.280143 1.690794 +v -10.832760 4.280143 1.690794 +v -10.885260 4.410196 1.407449 +v -10.885260 4.225875 1.642717 +v -10.885260 4.225875 1.642717 +v -10.832760 4.673283 1.208607 +v -10.832760 4.511012 1.477037 +v -10.832760 4.511012 1.477037 +v -10.832760 4.629010 1.185371 +v -10.832760 4.469863 1.448634 +v -10.832760 4.469863 1.448634 +v -10.885260 4.564815 1.151679 +v -10.885260 4.410196 1.407449 +v -10.885260 4.410196 1.407449 +v -10.832760 4.802016 0.922575 +v -10.832760 4.802016 0.922575 +v -10.832760 4.673283 1.208607 +v -10.832760 4.673283 1.208607 +v -10.832760 4.755265 0.904845 +v -10.832760 4.629010 1.185371 +v -10.832760 4.629010 1.185371 +v -10.885260 4.687476 0.879136 +v -10.885260 4.564815 1.151679 +v -10.885260 4.564815 1.151679 +v -10.832760 4.895332 0.623111 +v -10.832760 4.802016 0.922575 +v -10.832760 4.895332 0.623111 +v -10.885260 4.776392 0.593795 +v -10.885260 4.687476 0.879136 +v -10.885260 4.687476 0.879136 +v -10.832760 4.951872 0.314583 +v -10.832760 4.895332 0.623111 +v -10.832760 4.951872 0.314583 +v -10.885260 4.830266 0.299817 +v -10.885260 4.776392 0.593795 +v -10.885260 4.776392 0.593795 +v -10.832760 4.970811 0.001489 +v -10.832760 4.951872 0.314583 +v -10.832760 4.970811 0.001489 +v -10.832760 4.920811 0.001489 +v -10.832760 4.902237 0.308556 +v -10.832760 4.902237 0.308556 +v -10.885260 4.848311 0.001489 +v -10.885260 4.830266 0.299817 +v -10.885260 4.830266 0.299817 +v -10.832760 4.970811 0.001489 +v -10.832760 4.970811 0.001489 +v -10.832760 4.951872 -0.311605 +v -10.832760 4.902237 -0.305578 +v -10.832760 4.920811 0.001489 +v -10.832760 4.902237 -0.305578 +v -10.885260 4.830266 -0.296839 +v -10.885260 4.848311 0.001489 +v -10.885260 4.830266 -0.296839 +v -10.832760 4.951872 -0.311605 +v -10.832760 4.951872 -0.311605 +v -10.832760 4.895332 -0.620133 +v -10.885260 4.776392 -0.590817 +v -10.885260 4.830266 -0.296839 +v -10.885260 4.776392 -0.590817 +v -10.832760 4.895332 -0.620133 +v -10.832760 4.895332 -0.620133 +v -10.832760 4.802015 -0.919597 +v -10.885260 4.687476 -0.876158 +v -10.885260 4.776392 -0.590817 +v -10.885260 4.687476 -0.876158 +v -10.832760 4.802015 -0.919597 +v -10.832760 4.802015 -0.919597 +v -10.832760 4.673282 -1.205629 +v -10.832760 4.673282 -1.205629 +v -10.832760 4.629010 -1.182393 +v -10.832760 4.755265 -0.901867 +v -10.832760 4.629010 -1.182393 +v -10.885260 4.564814 -1.148700 +v -10.885260 4.687476 -0.876158 +v -10.885260 4.564814 -1.148700 +v -10.832760 4.511011 -1.474059 +v -10.832760 4.673282 -1.205629 +v -10.832760 4.511011 -1.474059 +v -10.832760 4.469862 -1.445655 +v -10.832760 4.629010 -1.182393 +v -10.832760 4.469862 -1.445655 +v -10.885260 4.410196 -1.404471 +v -10.885260 4.564814 -1.148700 +v -10.885260 4.410196 -1.404471 +v -10.832760 4.317567 -1.720971 +v -10.832760 4.511011 -1.474059 +v -10.832760 4.317567 -1.720971 +v -10.832760 4.280142 -1.687815 +v -10.832760 4.469862 -1.445655 +v -10.832760 4.280142 -1.687815 +v -10.885260 4.225874 -1.639739 +v -10.885260 4.410196 -1.404471 +v -10.885260 4.225874 -1.639739 +v -10.832760 4.095771 -1.942767 +v -10.832760 4.317567 -1.720971 +v -10.832760 4.095771 -1.942767 +v -10.832760 4.062616 -1.905342 +v -10.832760 4.280142 -1.687815 +v -10.832760 4.062616 -1.905342 +v -10.885260 4.014540 -1.851074 +v -10.885260 4.225874 -1.639739 +v -10.885260 4.014540 -1.851074 +v -10.832760 3.848859 -2.136211 +v -10.832760 4.095771 -1.942767 +v -10.832760 3.848859 -2.136211 +v -10.832760 3.820456 -2.095062 +v -10.832760 4.062616 -1.905342 +v -10.832760 3.820456 -2.095062 +v -10.885260 3.779271 -2.035395 +v -10.885260 4.014540 -1.851074 +v -10.885260 3.779271 -2.035395 +v -10.832760 3.580430 -2.298482 +v -10.832760 3.848859 -2.136211 +v -10.832760 3.580430 -2.298482 +v -10.832760 3.557194 -2.254210 +v -10.832760 3.820456 -2.095062 +v -10.832760 3.557194 -2.254210 +v -10.885260 3.523501 -2.190014 +v -10.885260 3.779271 -2.035395 +v -10.885260 3.523501 -2.190014 +v -10.832760 3.294397 -2.427215 +v -10.832760 3.580430 -2.298482 +v -10.832760 3.276667 -2.380464 +v -10.832760 3.557194 -2.254210 +v -10.832760 3.276667 -2.380464 +v -10.885260 3.250958 -2.312675 +v -10.885260 3.523501 -2.190014 +v -10.885260 3.250958 -2.312675 +v -10.832760 3.294397 -2.427215 +v -10.832760 3.294397 -2.427215 +v -10.832760 2.994934 -2.520531 +v -10.885260 2.965618 -2.401591 +v -10.885260 3.250958 -2.312675 +v -10.885260 2.965618 -2.401591 +v -10.832760 2.994934 2.523510 +v -10.832760 2.994934 2.523510 +v -10.832760 2.693312 2.578785 +v -10.832760 2.693312 2.578785 +v -10.832760 2.693312 2.528045 +v -10.832760 2.982969 2.474963 +v -10.832760 2.693312 2.528045 +v -10.885260 2.693312 2.454472 +v -10.885260 2.965618 2.404570 +v -10.885260 2.693312 2.454472 +v -10.832760 2.994934 -2.520531 +v -10.832760 2.994934 -2.520531 +v -10.832760 2.693311 -2.575806 +v -10.832760 2.693311 -2.575806 +v -10.832760 2.693311 -2.525066 +v -10.832760 2.693311 -2.525066 +v -10.832760 2.982968 -2.471984 +v -10.885260 2.693311 -2.451493 +v -10.885260 2.693311 -2.451493 +v -10.885260 2.965618 -2.401591 +# 1086 vertices + +vt 0.105211 0.240000 0.000000 +vt 0.141003 0.240000 0.000000 +vt 0.141003 0.275000 0.000000 +vt 0.105211 0.275000 0.000000 +vt 0.105211 0.390000 0.000000 +vt 0.141003 0.390000 0.000000 +vt 0.141003 0.425000 0.000000 +vt 0.105211 0.425000 0.000000 +vt 0.141003 0.570000 0.000000 +vt 0.105211 0.570000 0.000000 +vt 0.141003 0.950000 0.000000 +vt 0.176795 0.950000 0.000000 +vt 0.176795 1.000000 0.000000 +vt 0.141003 1.000000 0.000000 +vt 0.248380 0.390000 0.000000 +vt 0.284172 0.390000 0.000000 +vt 0.284172 0.425000 0.000000 +vt 0.248380 0.425000 0.000000 +vt 0.284172 0.275000 0.000000 +vt 0.319964 0.275000 0.000000 +vt 0.319964 0.325000 0.000000 +vt 0.284172 0.325000 0.000000 +vt 0.284172 0.355000 0.000000 +vt 0.319964 0.355000 0.000000 +vt 0.319964 0.390000 0.000000 +vt 0.319964 0.425000 0.000000 +vt 0.319964 0.900000 0.000000 +vt 0.355757 0.900000 0.000000 +vt 0.355757 0.950000 0.000000 +vt 0.319964 0.950000 0.000000 +vt 0.355757 1.000000 0.000000 +vt 0.319964 1.000000 0.000000 +vt 0.391549 0.900000 0.000000 +vt 0.391549 0.950000 0.000000 +vt 0.391549 1.000000 0.000000 +vt 0.391549 0.240000 0.000000 +vt 0.427341 0.240000 0.000000 +vt 0.427341 0.275000 0.000000 +vt 0.391549 0.275000 0.000000 +vt 0.391549 0.390000 0.000000 +vt 0.427341 0.390000 0.000000 +vt 0.427341 0.425000 0.000000 +vt 0.391549 0.425000 0.000000 +vt 0.427341 0.570000 0.000000 +vt 0.391549 0.570000 0.000000 +vt 0.463134 0.390000 0.000000 +vt 0.463134 0.425000 0.000000 +vt 0.463134 0.570000 0.000000 +vt 0.463134 0.240000 0.000000 +vt 0.498926 0.240000 0.000000 +vt 0.498926 0.275000 0.000000 +vt 0.463134 0.275000 0.000000 +vt 0.498926 0.390000 0.000000 +vt 0.498926 0.425000 0.000000 +vt 0.534718 0.240000 0.000000 +vt 0.534718 0.275000 0.000000 +vt 0.534718 0.390000 0.000000 +vt 0.534718 0.425000 0.000000 +vt 0.570511 0.390000 0.000000 +vt 0.570511 0.425000 0.000000 +vt 0.534718 0.570000 0.000000 +vt 0.570511 0.570000 0.000000 +vt 0.570511 0.275000 0.000000 +vt 0.570511 0.240000 0.000000 +vt 0.606303 0.240000 0.000000 +vt 0.606303 0.275000 0.000000 +vt 0.606303 0.390000 0.000000 +vt 0.606303 0.425000 0.000000 +vt 0.606303 0.570000 0.000000 +vt 0.606303 0.950000 0.000000 +vt 0.606303 0.900000 0.000000 +vt 0.642095 0.900000 0.000000 +vt 0.642095 0.950000 0.000000 +vt 0.606303 1.000000 0.000000 +vt 0.642095 1.000000 0.000000 +vt 0.677888 0.900000 0.000000 +vt 0.677888 0.950000 0.000000 +vt 0.677888 1.000000 0.000000 +vt 0.677888 0.325000 0.000000 +vt 0.677888 0.275000 0.000000 +vt 0.713680 0.275000 0.000000 +vt 0.713680 0.325000 0.000000 +vt 0.677888 0.390000 0.000000 +vt 0.677888 0.355000 0.000000 +vt 0.713680 0.355000 0.000000 +vt 0.713680 0.390000 0.000000 +vt 0.677888 0.425000 0.000000 +vt 0.713680 0.425000 0.000000 +vt 0.749472 0.390000 0.000000 +vt 0.749472 0.425000 0.000000 +vt 0.821057 1.000000 0.000000 +vt 0.821057 0.950000 0.000000 +vt 0.856849 0.950000 0.000000 +vt 0.856849 1.000000 0.000000 +vt 0.856849 0.275000 0.000000 +vt 0.856849 0.240000 0.000000 +vt 0.892641 0.240000 0.000000 +vt 0.892641 0.275000 0.000000 +vt 0.856849 0.425000 0.000000 +vt 0.856849 0.390000 0.000000 +vt 0.892641 0.390000 0.000000 +vt 0.892641 0.425000 0.000000 +vt 0.856849 0.570000 0.000000 +vt 0.892641 0.570000 0.000000 +vt 0.070911 0.425000 0.000000 +vt 0.070837 0.390000 0.000000 +vt 0.927015 0.390000 0.000000 +vt 0.926941 0.425000 0.000000 +vt 0.141003 0.275000 0.000000 +vt 0.141003 0.240000 0.000000 +vt 0.105211 0.240000 0.000000 +vt 0.105211 0.275000 0.000000 +vt 0.141003 0.425000 0.000000 +vt 0.141003 0.390000 0.000000 +vt 0.105211 0.390000 0.000000 +vt 0.105211 0.425000 0.000000 +vt 0.141003 0.570000 0.000000 +vt 0.105211 0.570000 0.000000 +vt 0.176795 1.000000 0.000000 +vt 0.176795 0.950000 0.000000 +vt 0.141003 0.950000 0.000000 +vt 0.141003 1.000000 0.000000 +vt 0.284172 0.425000 0.000000 +vt 0.284172 0.390000 0.000000 +vt 0.248380 0.390000 0.000000 +vt 0.248380 0.425000 0.000000 +vt 0.319964 0.325000 0.000000 +vt 0.319964 0.275000 0.000000 +vt 0.284172 0.275000 0.000000 +vt 0.284172 0.325000 0.000000 +vt 0.319964 0.390000 0.000000 +vt 0.319964 0.355000 0.000000 +vt 0.284172 0.355000 0.000000 +vt 0.319964 0.425000 0.000000 +vt 0.355757 0.950000 0.000000 +vt 0.355757 0.900000 0.000000 +vt 0.319964 0.900000 0.000000 +vt 0.319964 0.950000 0.000000 +vt 0.355757 1.000000 0.000000 +vt 0.319964 1.000000 0.000000 +vt 0.391549 0.950000 0.000000 +vt 0.391549 0.900000 0.000000 +vt 0.391549 1.000000 0.000000 +vt 0.427341 0.275000 0.000000 +vt 0.427341 0.240000 0.000000 +vt 0.391549 0.240000 0.000000 +vt 0.391549 0.275000 0.000000 +vt 0.427341 0.425000 0.000000 +vt 0.427341 0.390000 0.000000 +vt 0.391549 0.390000 0.000000 +vt 0.391549 0.425000 0.000000 +vt 0.427341 0.570000 0.000000 +vt 0.391549 0.570000 0.000000 +vt 0.463134 0.425000 0.000000 +vt 0.463134 0.390000 0.000000 +vt 0.463134 0.570000 0.000000 +vt 0.498926 0.275000 0.000000 +vt 0.498926 0.240000 0.000000 +vt 0.463134 0.240000 0.000000 +vt 0.463134 0.275000 0.000000 +vt 0.498926 0.425000 0.000000 +vt 0.498926 0.390000 0.000000 +vt 0.534718 0.240000 0.000000 +vt 0.534718 0.275000 0.000000 +vt 0.534718 0.390000 0.000000 +vt 0.534718 0.425000 0.000000 +vt 0.570511 0.390000 0.000000 +vt 0.570511 0.425000 0.000000 +vt 0.534718 0.570000 0.000000 +vt 0.570511 0.570000 0.000000 +vt 0.606303 0.240000 0.000000 +vt 0.570511 0.240000 0.000000 +vt 0.570511 0.275000 0.000000 +vt 0.606303 0.275000 0.000000 +vt 0.606303 0.390000 0.000000 +vt 0.606303 0.425000 0.000000 +vt 0.606303 0.570000 0.000000 +vt 0.642095 0.900000 0.000000 +vt 0.606303 0.900000 0.000000 +vt 0.606303 0.950000 0.000000 +vt 0.642095 0.950000 0.000000 +vt 0.606303 1.000000 0.000000 +vt 0.642095 1.000000 0.000000 +vt 0.677888 0.900000 0.000000 +vt 0.677888 0.950000 0.000000 +vt 0.677888 1.000000 0.000000 +vt 0.713680 0.275000 0.000000 +vt 0.677888 0.275000 0.000000 +vt 0.677888 0.325000 0.000000 +vt 0.713680 0.325000 0.000000 +vt 0.713680 0.355000 0.000000 +vt 0.677888 0.355000 0.000000 +vt 0.677888 0.390000 0.000000 +vt 0.713680 0.390000 0.000000 +vt 0.677888 0.425000 0.000000 +vt 0.713680 0.425000 0.000000 +vt 0.749472 0.390000 0.000000 +vt 0.749472 0.425000 0.000000 +vt 0.856849 0.950000 0.000000 +vt 0.821057 0.950000 0.000000 +vt 0.821057 1.000000 0.000000 +vt 0.856849 1.000000 0.000000 +vt 0.892641 0.240000 0.000000 +vt 0.856849 0.240000 0.000000 +vt 0.856849 0.275000 0.000000 +vt 0.892641 0.275000 0.000000 +vt 0.892641 0.390000 0.000000 +vt 0.856849 0.390000 0.000000 +vt 0.856849 0.425000 0.000000 +vt 0.892641 0.425000 0.000000 +vt 0.856849 0.570000 0.000000 +vt 0.892641 0.570000 0.000000 +vt 0.070837 0.390000 0.000000 +vt 0.070911 0.425000 0.000000 +vt 0.926941 0.425000 0.000000 +vt 0.927015 0.390000 0.000000 +vt 0.105211 0.000000 0.000000 +vt 0.141003 0.000000 0.000000 +vt 0.141003 0.325000 0.000000 +vt 0.105211 0.325000 0.000000 +vt 0.141003 0.355000 0.000000 +vt 0.105211 0.355000 0.000000 +vt 0.141003 0.700000 0.000000 +vt 0.105211 0.700000 0.000000 +vt 0.141003 0.845000 0.000000 +vt 0.105211 0.845000 0.000000 +vt 0.141003 0.900000 0.000000 +vt 0.105211 0.900000 0.000000 +vt 0.105211 0.950000 0.000000 +vt 0.105211 1.000000 0.000000 +vt 0.176795 0.000000 0.000000 +vt 0.176795 0.225000 0.000000 +vt 0.176795 0.275000 0.000000 +vt 0.176795 0.325000 0.000000 +vt 0.176795 0.355000 0.000000 +vt 0.176795 0.390000 0.000000 +vt 0.176795 0.425000 0.000000 +vt 0.176795 0.570000 0.000000 +vt 0.176795 0.700000 0.000000 +vt 0.176795 0.845000 0.000000 +vt 0.176795 0.900000 0.000000 +vt 0.212588 0.000000 0.000000 +vt 0.212588 0.225000 0.000000 +vt 0.212588 0.275000 0.000000 +vt 0.212588 0.325000 0.000000 +vt 0.212588 0.355000 0.000000 +vt 0.212588 0.390000 0.000000 +vt 0.212588 0.425000 0.000000 +vt 0.212588 0.570000 0.000000 +vt 0.212588 0.700000 0.000000 +vt 0.212588 0.845000 0.000000 +vt 0.212588 0.900000 0.000000 +vt 0.212588 0.950000 0.000000 +vt 0.212588 1.000000 0.000000 +vt 0.248380 0.000000 0.000000 +vt 0.248380 0.225000 0.000000 +vt 0.248380 0.275000 0.000000 +vt 0.248380 0.325000 0.000000 +vt 0.248380 0.355000 0.000000 +vt 0.248380 0.570000 0.000000 +vt 0.248380 0.700000 0.000000 +vt 0.248380 0.845000 0.000000 +vt 0.248380 0.900000 0.000000 +vt 0.248380 0.950000 0.000000 +vt 0.248380 1.000000 0.000000 +vt 0.284172 0.000000 0.000000 +vt 0.284172 0.225000 0.000000 +vt 0.284172 0.570000 0.000000 +vt 0.284172 0.700000 0.000000 +vt 0.284172 0.845000 0.000000 +vt 0.284172 0.900000 0.000000 +vt 0.284172 0.950000 0.000000 +vt 0.284172 1.000000 0.000000 +vt 0.319964 0.000000 0.000000 +vt 0.319964 0.225000 0.000000 +vt 0.319964 0.570000 0.000000 +vt 0.319964 0.700000 0.000000 +vt 0.319964 0.845000 0.000000 +vt 0.355757 0.000000 0.000000 +vt 0.355757 0.225000 0.000000 +vt 0.355757 0.275000 0.000000 +vt 0.355757 0.325000 0.000000 +vt 0.355757 0.355000 0.000000 +vt 0.355757 0.390000 0.000000 +vt 0.355757 0.425000 0.000000 +vt 0.355757 0.570000 0.000000 +vt 0.355757 0.700000 0.000000 +vt 0.355757 0.845000 0.000000 +vt 0.391549 0.000000 0.000000 +vt 0.391549 0.325000 0.000000 +vt 0.391549 0.355000 0.000000 +vt 0.391549 0.700000 0.000000 +vt 0.391549 0.845000 0.000000 +vt 0.427341 0.000000 0.000000 +vt 0.427341 0.325000 0.000000 +vt 0.427341 0.355000 0.000000 +vt 0.427341 0.700000 0.000000 +vt 0.427341 0.845000 0.000000 +vt 0.427341 0.900000 0.000000 +vt 0.427341 0.950000 0.000000 +vt 0.427341 1.000000 0.000000 +vt 0.463134 0.000000 0.000000 +vt 0.463134 0.325000 0.000000 +vt 0.463134 0.355000 0.000000 +vt 0.463134 0.700000 0.000000 +vt 0.463134 0.845000 0.000000 +vt 0.463134 0.900000 0.000000 +vt 0.463134 0.950000 0.000000 +vt 0.463134 1.000000 0.000000 +vt 0.498926 0.000000 0.000000 +vt 0.498926 0.325000 0.000000 +vt 0.498926 0.355000 0.000000 +vt 0.498926 0.570000 0.000000 +vt 0.498926 0.700000 0.000000 +vt 0.498926 0.845000 0.000000 +vt 0.498926 0.900000 0.000000 +vt 0.498926 0.950000 0.000000 +vt 0.498926 1.000000 0.000000 +vt 0.534718 0.000000 0.000000 +vt 0.534718 0.325000 0.000000 +vt 0.534718 0.355000 0.000000 +vt 0.534718 0.700000 0.000000 +vt 0.534718 0.845000 0.000000 +vt 0.534718 0.900000 0.000000 +vt 0.534718 0.950000 0.000000 +vt 0.534718 1.000000 0.000000 +vt 0.570511 0.000000 0.000000 +vt 0.570511 0.325000 0.000000 +vt 0.570511 0.355000 0.000000 +vt 0.570511 0.700000 0.000000 +vt 0.570511 0.845000 0.000000 +vt 0.570511 0.900000 0.000000 +vt 0.570511 0.950000 0.000000 +vt 0.570511 1.000000 0.000000 +vt 0.606303 0.000000 0.000000 +vt 0.606303 0.325000 0.000000 +vt 0.606303 0.355000 0.000000 +vt 0.606303 0.700000 0.000000 +vt 0.606303 0.845000 0.000000 +vt 0.642095 0.000000 0.000000 +vt 0.642095 0.225000 0.000000 +vt 0.642095 0.275000 0.000000 +vt 0.642095 0.325000 0.000000 +vt 0.642095 0.355000 0.000000 +vt 0.642095 0.390000 0.000000 +vt 0.642095 0.425000 0.000000 +vt 0.642095 0.570000 0.000000 +vt 0.642095 0.700000 0.000000 +vt 0.642095 0.845000 0.000000 +vt 0.677888 0.000000 0.000000 +vt 0.677888 0.225000 0.000000 +vt 0.677888 0.570000 0.000000 +vt 0.677888 0.700000 0.000000 +vt 0.677888 0.845000 0.000000 +vt 0.713680 0.000000 0.000000 +vt 0.713680 0.225000 0.000000 +vt 0.713680 0.570000 0.000000 +vt 0.713680 0.700000 0.000000 +vt 0.713680 0.845000 0.000000 +vt 0.713680 0.900000 0.000000 +vt 0.713680 0.950000 0.000000 +vt 0.713680 1.000000 0.000000 +vt 0.749472 0.000000 0.000000 +vt 0.749472 0.225000 0.000000 +vt 0.749472 0.275000 0.000000 +vt 0.749472 0.325000 0.000000 +vt 0.749472 0.355000 0.000000 +vt 0.749472 0.570000 0.000000 +vt 0.749472 0.700000 0.000000 +vt 0.749472 0.845000 0.000000 +vt 0.749472 0.900000 0.000000 +vt 0.749472 0.950000 0.000000 +vt 0.749472 1.000000 0.000000 +vt 0.785264 0.000000 0.000000 +vt 0.785264 0.225000 0.000000 +vt 0.785264 0.275000 0.000000 +vt 0.785264 0.325000 0.000000 +vt 0.785264 0.355000 0.000000 +vt 0.785264 0.390000 0.000000 +vt 0.785264 0.425000 0.000000 +vt 0.785264 0.570000 0.000000 +vt 0.785264 0.700000 0.000000 +vt 0.785264 0.845000 0.000000 +vt 0.785264 0.900000 0.000000 +vt 0.785264 0.950000 0.000000 +vt 0.785264 1.000000 0.000000 +vt 0.821057 0.000000 0.000000 +vt 0.821057 0.225000 0.000000 +vt 0.821057 0.275000 0.000000 +vt 0.821057 0.325000 0.000000 +vt 0.821057 0.355000 0.000000 +vt 0.821057 0.390000 0.000000 +vt 0.821057 0.425000 0.000000 +vt 0.821057 0.570000 0.000000 +vt 0.821057 0.700000 0.000000 +vt 0.821057 0.845000 0.000000 +vt 0.821057 0.900000 0.000000 +vt 0.856849 0.000000 0.000000 +vt 0.856849 0.325000 0.000000 +vt 0.856849 0.355000 0.000000 +vt 0.856849 0.700000 0.000000 +vt 0.856849 0.845000 0.000000 +vt 0.856849 0.900000 0.000000 +vt 0.892641 0.000000 0.000000 +vt 0.892641 0.325000 0.000000 +vt 0.892641 0.355000 0.000000 +vt 0.892641 0.700000 0.000000 +vt 0.892641 0.845000 0.000000 +vt 0.892641 0.900000 0.000000 +vt 0.892641 0.950000 0.000000 +vt 0.892641 1.000000 0.000000 +vt 0.070184 0.225000 0.000000 +vt 0.070184 0.000000 0.000000 +vt 0.070327 0.275000 0.000000 +vt 0.070471 0.325000 0.000000 +vt 0.070690 0.355000 0.000000 +vt 0.071195 0.570000 0.000000 +vt 0.071567 0.700000 0.000000 +vt 0.072057 0.845000 0.000000 +vt 0.072263 0.900000 0.000000 +vt 0.072519 0.950000 0.000000 +vt 0.072616 1.000000 0.000000 +vt 0.927668 0.000000 0.000000 +vt 0.927668 0.225000 0.000000 +vt 0.927525 0.275000 0.000000 +vt 0.927381 0.325000 0.000000 +vt 0.927162 0.355000 0.000000 +vt 0.926657 0.570000 0.000000 +vt 0.926285 0.700000 0.000000 +vt 0.925795 0.845000 0.000000 +vt 0.925589 0.900000 0.000000 +vt 0.925333 0.950000 0.000000 +vt 0.925236 1.000000 0.000000 +vt 0.141003 0.000000 0.000000 +vt 0.105211 0.000000 0.000000 +vt 0.141003 0.325000 0.000000 +vt 0.105211 0.325000 0.000000 +vt 0.141003 0.355000 0.000000 +vt 0.105211 0.355000 0.000000 +vt 0.141003 0.700000 0.000000 +vt 0.105211 0.700000 0.000000 +vt 0.141003 0.845000 0.000000 +vt 0.105211 0.845000 0.000000 +vt 0.141003 0.900000 0.000000 +vt 0.105211 0.900000 0.000000 +vt 0.105211 0.950000 0.000000 +vt 0.105211 1.000000 0.000000 +vt 0.176795 0.225000 0.000000 +vt 0.176795 0.000000 0.000000 +vt 0.176795 0.275000 0.000000 +vt 0.176795 0.325000 0.000000 +vt 0.176795 0.355000 0.000000 +vt 0.176795 0.390000 0.000000 +vt 0.176795 0.425000 0.000000 +vt 0.176795 0.570000 0.000000 +vt 0.176795 0.700000 0.000000 +vt 0.176795 0.845000 0.000000 +vt 0.176795 0.900000 0.000000 +vt 0.212588 0.225000 0.000000 +vt 0.212588 0.000000 0.000000 +vt 0.212588 0.275000 0.000000 +vt 0.212588 0.325000 0.000000 +vt 0.212588 0.355000 0.000000 +vt 0.212588 0.390000 0.000000 +vt 0.212588 0.425000 0.000000 +vt 0.212588 0.570000 0.000000 +vt 0.212588 0.700000 0.000000 +vt 0.212588 0.845000 0.000000 +vt 0.212588 0.900000 0.000000 +vt 0.212588 0.950000 0.000000 +vt 0.212588 1.000000 0.000000 +vt 0.248380 0.225000 0.000000 +vt 0.248380 0.000000 0.000000 +vt 0.248380 0.275000 0.000000 +vt 0.248380 0.325000 0.000000 +vt 0.248380 0.355000 0.000000 +vt 0.248380 0.570000 0.000000 +vt 0.248380 0.700000 0.000000 +vt 0.248380 0.845000 0.000000 +vt 0.248380 0.900000 0.000000 +vt 0.248380 0.950000 0.000000 +vt 0.248380 1.000000 0.000000 +vt 0.284172 0.225000 0.000000 +vt 0.284172 0.000000 0.000000 +vt 0.284172 0.570000 0.000000 +vt 0.284172 0.700000 0.000000 +vt 0.284172 0.845000 0.000000 +vt 0.284172 0.900000 0.000000 +vt 0.284172 0.950000 0.000000 +vt 0.284172 1.000000 0.000000 +vt 0.319964 0.225000 0.000000 +vt 0.319964 0.000000 0.000000 +vt 0.319964 0.570000 0.000000 +vt 0.319964 0.700000 0.000000 +vt 0.319964 0.845000 0.000000 +vt 0.355757 0.225000 0.000000 +vt 0.355757 0.000000 0.000000 +vt 0.355757 0.275000 0.000000 +vt 0.355757 0.325000 0.000000 +vt 0.355757 0.355000 0.000000 +vt 0.355757 0.390000 0.000000 +vt 0.355757 0.425000 0.000000 +vt 0.355757 0.570000 0.000000 +vt 0.355757 0.700000 0.000000 +vt 0.355757 0.845000 0.000000 +vt 0.391549 0.000000 0.000000 +vt 0.391549 0.325000 0.000000 +vt 0.391549 0.355000 0.000000 +vt 0.391549 0.700000 0.000000 +vt 0.391549 0.845000 0.000000 +vt 0.427341 0.000000 0.000000 +vt 0.427341 0.325000 0.000000 +vt 0.427341 0.355000 0.000000 +vt 0.427341 0.700000 0.000000 +vt 0.427341 0.845000 0.000000 +vt 0.427341 0.900000 0.000000 +vt 0.427341 0.950000 0.000000 +vt 0.427341 1.000000 0.000000 +vt 0.463134 0.000000 0.000000 +vt 0.463134 0.325000 0.000000 +vt 0.463134 0.355000 0.000000 +vt 0.463134 0.700000 0.000000 +vt 0.463134 0.845000 0.000000 +vt 0.463134 0.900000 0.000000 +vt 0.463134 0.950000 0.000000 +vt 0.463134 1.000000 0.000000 +vt 0.498926 0.000000 0.000000 +vt 0.498926 0.325000 0.000000 +vt 0.498926 0.355000 0.000000 +vt 0.498926 0.570000 0.000000 +vt 0.498926 0.700000 0.000000 +vt 0.498926 0.845000 0.000000 +vt 0.498926 0.900000 0.000000 +vt 0.498926 0.950000 0.000000 +vt 0.498926 1.000000 0.000000 +vt 0.534718 0.000000 0.000000 +vt 0.534718 0.325000 0.000000 +vt 0.534718 0.355000 0.000000 +vt 0.534718 0.700000 0.000000 +vt 0.534718 0.845000 0.000000 +vt 0.534718 0.900000 0.000000 +vt 0.534718 0.950000 0.000000 +vt 0.534718 1.000000 0.000000 +vt 0.570511 0.000000 0.000000 +vt 0.570511 0.325000 0.000000 +vt 0.570511 0.355000 0.000000 +vt 0.570511 0.700000 0.000000 +vt 0.570511 0.845000 0.000000 +vt 0.570511 0.900000 0.000000 +vt 0.570511 0.950000 0.000000 +vt 0.570511 1.000000 0.000000 +vt 0.606303 0.000000 0.000000 +vt 0.606303 0.325000 0.000000 +vt 0.606303 0.355000 0.000000 +vt 0.606303 0.700000 0.000000 +vt 0.606303 0.845000 0.000000 +vt 0.642095 0.000000 0.000000 +vt 0.642095 0.225000 0.000000 +vt 0.642095 0.275000 0.000000 +vt 0.642095 0.325000 0.000000 +vt 0.642095 0.355000 0.000000 +vt 0.642095 0.390000 0.000000 +vt 0.642095 0.425000 0.000000 +vt 0.642095 0.570000 0.000000 +vt 0.642095 0.700000 0.000000 +vt 0.642095 0.845000 0.000000 +vt 0.677888 0.000000 0.000000 +vt 0.677888 0.225000 0.000000 +vt 0.677888 0.570000 0.000000 +vt 0.677888 0.700000 0.000000 +vt 0.677888 0.845000 0.000000 +vt 0.713680 0.000000 0.000000 +vt 0.713680 0.225000 0.000000 +vt 0.713680 0.570000 0.000000 +vt 0.713680 0.700000 0.000000 +vt 0.713680 0.845000 0.000000 +vt 0.713680 0.900000 0.000000 +vt 0.713680 0.950000 0.000000 +vt 0.713680 1.000000 0.000000 +vt 0.749472 0.000000 0.000000 +vt 0.749472 0.225000 0.000000 +vt 0.749472 0.275000 0.000000 +vt 0.749472 0.325000 0.000000 +vt 0.749472 0.355000 0.000000 +vt 0.749472 0.570000 0.000000 +vt 0.749472 0.700000 0.000000 +vt 0.749472 0.845000 0.000000 +vt 0.749472 0.900000 0.000000 +vt 0.749472 0.950000 0.000000 +vt 0.749472 1.000000 0.000000 +vt 0.785264 0.000000 0.000000 +vt 0.785264 0.225000 0.000000 +vt 0.785264 0.275000 0.000000 +vt 0.785264 0.325000 0.000000 +vt 0.785264 0.355000 0.000000 +vt 0.785264 0.390000 0.000000 +vt 0.785264 0.425000 0.000000 +vt 0.785264 0.570000 0.000000 +vt 0.785264 0.700000 0.000000 +vt 0.785264 0.845000 0.000000 +vt 0.785264 0.900000 0.000000 +vt 0.785264 0.950000 0.000000 +vt 0.785264 1.000000 0.000000 +vt 0.821057 0.000000 0.000000 +vt 0.821057 0.225000 0.000000 +vt 0.821057 0.275000 0.000000 +vt 0.821057 0.325000 0.000000 +vt 0.821057 0.355000 0.000000 +vt 0.821057 0.390000 0.000000 +vt 0.821057 0.425000 0.000000 +vt 0.821057 0.570000 0.000000 +vt 0.821057 0.700000 0.000000 +vt 0.821057 0.845000 0.000000 +vt 0.821057 0.900000 0.000000 +vt 0.856849 0.000000 0.000000 +vt 0.856849 0.325000 0.000000 +vt 0.856849 0.355000 0.000000 +vt 0.856849 0.700000 0.000000 +vt 0.856849 0.845000 0.000000 +vt 0.856849 0.900000 0.000000 +vt 0.892641 0.000000 0.000000 +vt 0.892641 0.325000 0.000000 +vt 0.892641 0.355000 0.000000 +vt 0.892641 0.700000 0.000000 +vt 0.892641 0.845000 0.000000 +vt 0.892641 0.900000 0.000000 +vt 0.892641 0.950000 0.000000 +vt 0.892641 1.000000 0.000000 +vt 0.070184 0.000000 0.000000 +vt 0.070184 0.225000 0.000000 +vt 0.070327 0.275000 0.000000 +vt 0.070471 0.325000 0.000000 +vt 0.070690 0.355000 0.000000 +vt 0.071195 0.570000 0.000000 +vt 0.071567 0.700000 0.000000 +vt 0.072057 0.845000 0.000000 +vt 0.072263 0.900000 0.000000 +vt 0.072519 0.950000 0.000000 +vt 0.072616 1.000000 0.000000 +vt 0.927668 0.225000 0.000000 +vt 0.927668 0.000000 0.000000 +vt 0.927525 0.275000 0.000000 +vt 0.927381 0.325000 0.000000 +vt 0.927162 0.355000 0.000000 +vt 0.926657 0.570000 0.000000 +vt 0.926285 0.700000 0.000000 +vt 0.925795 0.845000 0.000000 +vt 0.925589 0.900000 0.000000 +vt 0.925333 0.950000 0.000000 +vt 0.925236 1.000000 0.000000 +vt 0.105211 0.440000 0.000000 +vt 0.141003 0.440000 0.000000 +vt 0.105211 0.440000 0.000000 +vt 0.391549 0.440000 0.000000 +vt 0.427341 0.440000 0.000000 +vt 0.391549 0.440000 0.000000 +vt 0.427341 0.440000 0.000000 +vt 0.463134 0.440000 0.000000 +vt 0.427341 0.440000 0.000000 +vt 0.534718 0.440000 0.000000 +vt 0.570511 0.440000 0.000000 +vt 0.570511 0.440000 0.000000 +vt 0.570511 0.440000 0.000000 +vt 0.606303 0.440000 0.000000 +vt 0.606303 0.440000 0.000000 +vt 0.856849 0.440000 0.000000 +vt 0.892641 0.440000 0.000000 +vt 0.892641 0.440000 0.000000 +vt 0.141003 0.440000 0.000000 +vt 0.105211 0.440000 0.000000 +vt 0.105211 0.440000 0.000000 +vt 0.427341 0.440000 0.000000 +vt 0.391549 0.440000 0.000000 +vt 0.391549 0.440000 0.000000 +vt 0.463134 0.440000 0.000000 +vt 0.427341 0.440000 0.000000 +vt 0.427341 0.440000 0.000000 +vt 0.570511 0.440000 0.000000 +vt 0.534718 0.440000 0.000000 +vt 0.570511 0.440000 0.000000 +vt 0.606303 0.440000 0.000000 +vt 0.570511 0.440000 0.000000 +vt 0.606303 0.440000 0.000000 +vt 0.892641 0.440000 0.000000 +vt 0.856849 0.440000 0.000000 +vt 0.892641 0.440000 0.000000 +vt 0.141003 0.225000 0.000000 +vt 0.141003 0.225000 0.000000 +vt 0.105211 0.225000 0.000000 +vt 0.105211 0.860000 0.000000 +vt 0.141003 0.860000 0.000000 +vt 0.105211 0.860000 0.000000 +vt 0.141003 0.225000 0.000000 +vt 0.176795 0.240000 0.000000 +vt 0.141003 0.440000 0.000000 +vt 0.176795 0.440000 0.000000 +vt 0.141003 0.440000 0.000000 +vt 0.141003 0.860000 0.000000 +vt 0.176795 0.860000 0.000000 +vt 0.141003 0.860000 0.000000 +vt 0.176795 0.240000 0.000000 +vt 0.212588 0.240000 0.000000 +vt 0.176795 0.240000 0.000000 +vt 0.176795 0.440000 0.000000 +vt 0.212588 0.440000 0.000000 +vt 0.176795 0.440000 0.000000 +vt 0.176795 0.860000 0.000000 +vt 0.212588 0.860000 0.000000 +vt 0.176795 0.860000 0.000000 +vt 0.212588 0.240000 0.000000 +vt 0.248380 0.240000 0.000000 +vt 0.212588 0.240000 0.000000 +vt 0.212588 0.440000 0.000000 +vt 0.248380 0.440000 0.000000 +vt 0.212588 0.440000 0.000000 +vt 0.212588 0.860000 0.000000 +vt 0.248380 0.860000 0.000000 +vt 0.212588 0.860000 0.000000 +vt 0.248380 0.240000 0.000000 +vt 0.284172 0.240000 0.000000 +vt 0.248380 0.240000 0.000000 +vt 0.248380 0.440000 0.000000 +vt 0.284172 0.440000 0.000000 +vt 0.248380 0.440000 0.000000 +vt 0.248380 0.860000 0.000000 +vt 0.284172 0.860000 0.000000 +vt 0.248380 0.860000 0.000000 +vt 0.284172 0.240000 0.000000 +vt 0.319964 0.240000 0.000000 +vt 0.284172 0.240000 0.000000 +vt 0.284172 0.440000 0.000000 +vt 0.319964 0.440000 0.000000 +vt 0.284172 0.440000 0.000000 +vt 0.284172 0.860000 0.000000 +vt 0.319964 0.860000 0.000000 +vt 0.284172 0.860000 0.000000 +vt 0.319964 0.240000 0.000000 +vt 0.355757 0.240000 0.000000 +vt 0.319964 0.240000 0.000000 +vt 0.319964 0.440000 0.000000 +vt 0.355757 0.440000 0.000000 +vt 0.319964 0.440000 0.000000 +vt 0.319964 0.860000 0.000000 +vt 0.355757 0.860000 0.000000 +vt 0.319964 0.860000 0.000000 +vt 0.391549 0.225000 0.000000 +vt 0.391549 0.225000 0.000000 +vt 0.355757 0.240000 0.000000 +vt 0.355757 0.240000 0.000000 +vt 0.355757 0.440000 0.000000 +vt 0.391549 0.440000 0.000000 +vt 0.355757 0.440000 0.000000 +vt 0.355757 0.860000 0.000000 +vt 0.391549 0.860000 0.000000 +vt 0.355757 0.860000 0.000000 +vt 0.427341 0.225000 0.000000 +vt 0.427341 0.225000 0.000000 +vt 0.391549 0.225000 0.000000 +vt 0.391549 0.860000 0.000000 +vt 0.427341 0.860000 0.000000 +vt 0.391549 0.860000 0.000000 +vt 0.463134 0.225000 0.000000 +vt 0.463134 0.225000 0.000000 +vt 0.427341 0.225000 0.000000 +vt 0.427341 0.860000 0.000000 +vt 0.463134 0.860000 0.000000 +vt 0.427341 0.860000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.463134 0.225000 0.000000 +vt 0.463134 0.440000 0.000000 +vt 0.498926 0.440000 0.000000 +vt 0.463134 0.440000 0.000000 +vt 0.463134 0.860000 0.000000 +vt 0.498926 0.860000 0.000000 +vt 0.463134 0.860000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.534718 0.225000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.498926 0.440000 0.000000 +vt 0.534718 0.440000 0.000000 +vt 0.534718 0.440000 0.000000 +vt 0.498926 0.860000 0.000000 +vt 0.534718 0.860000 0.000000 +vt 0.534718 0.860000 0.000000 +vt 0.534718 0.225000 0.000000 +vt 0.570511 0.225000 0.000000 +vt 0.534718 0.225000 0.000000 +vt 0.534718 0.860000 0.000000 +vt 0.570511 0.860000 0.000000 +vt 0.570511 0.860000 0.000000 +vt 0.570511 0.225000 0.000000 +vt 0.606303 0.225000 0.000000 +vt 0.570511 0.225000 0.000000 +vt 0.570511 0.860000 0.000000 +vt 0.606303 0.860000 0.000000 +vt 0.606303 0.860000 0.000000 +vt 0.606303 0.225000 0.000000 +vt 0.606303 0.225000 0.000000 +vt 0.642095 0.240000 0.000000 +vt 0.642095 0.240000 0.000000 +vt 0.606303 0.440000 0.000000 +vt 0.642095 0.440000 0.000000 +vt 0.642095 0.440000 0.000000 +vt 0.606303 0.860000 0.000000 +vt 0.642095 0.860000 0.000000 +vt 0.642095 0.860000 0.000000 +vt 0.642095 0.240000 0.000000 +vt 0.677888 0.240000 0.000000 +vt 0.677888 0.240000 0.000000 +vt 0.642095 0.440000 0.000000 +vt 0.677888 0.440000 0.000000 +vt 0.677888 0.440000 0.000000 +vt 0.642095 0.860000 0.000000 +vt 0.677888 0.860000 0.000000 +vt 0.677888 0.860000 0.000000 +vt 0.677888 0.240000 0.000000 +vt 0.713680 0.240000 0.000000 +vt 0.713680 0.240000 0.000000 +vt 0.677888 0.440000 0.000000 +vt 0.713680 0.440000 0.000000 +vt 0.713680 0.440000 0.000000 +vt 0.677888 0.860000 0.000000 +vt 0.713680 0.860000 0.000000 +vt 0.713680 0.860000 0.000000 +vt 0.713680 0.240000 0.000000 +vt 0.749472 0.240000 0.000000 +vt 0.749472 0.240000 0.000000 +vt 0.713680 0.440000 0.000000 +vt 0.749472 0.440000 0.000000 +vt 0.749472 0.440000 0.000000 +vt 0.713680 0.860000 0.000000 +vt 0.749472 0.860000 0.000000 +vt 0.749472 0.860000 0.000000 +vt 0.749472 0.240000 0.000000 +vt 0.785264 0.240000 0.000000 +vt 0.785264 0.240000 0.000000 +vt 0.749472 0.440000 0.000000 +vt 0.785264 0.440000 0.000000 +vt 0.785264 0.440000 0.000000 +vt 0.749472 0.860000 0.000000 +vt 0.785264 0.860000 0.000000 +vt 0.785264 0.860000 0.000000 +vt 0.785264 0.240000 0.000000 +vt 0.821057 0.240000 0.000000 +vt 0.821057 0.240000 0.000000 +vt 0.785264 0.440000 0.000000 +vt 0.821057 0.440000 0.000000 +vt 0.821057 0.440000 0.000000 +vt 0.785264 0.860000 0.000000 +vt 0.821057 0.860000 0.000000 +vt 0.821057 0.860000 0.000000 +vt 0.856849 0.225000 0.000000 +vt 0.821057 0.240000 0.000000 +vt 0.821057 0.440000 0.000000 +vt 0.856849 0.440000 0.000000 +vt 0.856849 0.440000 0.000000 +vt 0.821057 0.860000 0.000000 +vt 0.856849 0.860000 0.000000 +vt 0.856849 0.860000 0.000000 +vt 0.856849 0.225000 0.000000 +vt 0.892641 0.225000 0.000000 +vt 0.856849 0.225000 0.000000 +vt 0.856849 0.860000 0.000000 +vt 0.892641 0.860000 0.000000 +vt 0.892641 0.860000 0.000000 +vt 0.105211 0.225000 0.000000 +vt 0.105211 0.225000 0.000000 +vt 0.070255 0.240000 0.000000 +vt 0.070255 0.240000 0.000000 +vt 0.070985 0.440000 0.000000 +vt 0.070985 0.440000 0.000000 +vt 0.105211 0.440000 0.000000 +vt 0.072057 0.860000 0.000000 +vt 0.072057 0.860000 0.000000 +vt 0.105211 0.860000 0.000000 +vt 0.892641 0.225000 0.000000 +vt 0.892641 0.225000 0.000000 +vt 0.927597 0.240000 0.000000 +vt 0.927597 0.240000 0.000000 +vt 0.926867 0.440000 0.000000 +vt 0.892641 0.440000 0.000000 +vt 0.926867 0.440000 0.000000 +vt 0.925795 0.860000 0.000000 +vt 0.892641 0.860000 0.000000 +vt 0.925795 0.860000 0.000000 +vt 0.141003 0.225000 0.000000 +vt 0.105211 0.225000 0.000000 +vt 0.141003 0.225000 0.000000 +vt 0.141003 0.860000 0.000000 +vt 0.105211 0.860000 0.000000 +vt 0.105211 0.860000 0.000000 +vt 0.141003 0.225000 0.000000 +vt 0.176795 0.240000 0.000000 +vt 0.176795 0.440000 0.000000 +vt 0.141003 0.440000 0.000000 +vt 0.141003 0.440000 0.000000 +vt 0.176795 0.860000 0.000000 +vt 0.141003 0.860000 0.000000 +vt 0.141003 0.860000 0.000000 +vt 0.212588 0.240000 0.000000 +vt 0.176795 0.240000 0.000000 +vt 0.176795 0.240000 0.000000 +vt 0.212588 0.440000 0.000000 +vt 0.176795 0.440000 0.000000 +vt 0.176795 0.440000 0.000000 +vt 0.212588 0.860000 0.000000 +vt 0.176795 0.860000 0.000000 +vt 0.176795 0.860000 0.000000 +vt 0.248380 0.240000 0.000000 +vt 0.212588 0.240000 0.000000 +vt 0.212588 0.240000 0.000000 +vt 0.248380 0.440000 0.000000 +vt 0.212588 0.440000 0.000000 +vt 0.212588 0.440000 0.000000 +vt 0.248380 0.860000 0.000000 +vt 0.212588 0.860000 0.000000 +vt 0.212588 0.860000 0.000000 +vt 0.284172 0.240000 0.000000 +vt 0.248380 0.240000 0.000000 +vt 0.248380 0.240000 0.000000 +vt 0.284172 0.440000 0.000000 +vt 0.248380 0.440000 0.000000 +vt 0.248380 0.440000 0.000000 +vt 0.284172 0.860000 0.000000 +vt 0.248380 0.860000 0.000000 +vt 0.248380 0.860000 0.000000 +vt 0.319964 0.240000 0.000000 +vt 0.284172 0.240000 0.000000 +vt 0.284172 0.240000 0.000000 +vt 0.319964 0.440000 0.000000 +vt 0.284172 0.440000 0.000000 +vt 0.284172 0.440000 0.000000 +vt 0.319964 0.860000 0.000000 +vt 0.284172 0.860000 0.000000 +vt 0.284172 0.860000 0.000000 +vt 0.355757 0.240000 0.000000 +vt 0.319964 0.240000 0.000000 +vt 0.319964 0.240000 0.000000 +vt 0.355757 0.440000 0.000000 +vt 0.319964 0.440000 0.000000 +vt 0.319964 0.440000 0.000000 +vt 0.355757 0.860000 0.000000 +vt 0.319964 0.860000 0.000000 +vt 0.319964 0.860000 0.000000 +vt 0.391549 0.225000 0.000000 +vt 0.391549 0.225000 0.000000 +vt 0.355757 0.240000 0.000000 +vt 0.355757 0.240000 0.000000 +vt 0.391549 0.440000 0.000000 +vt 0.355757 0.440000 0.000000 +vt 0.355757 0.440000 0.000000 +vt 0.391549 0.860000 0.000000 +vt 0.355757 0.860000 0.000000 +vt 0.355757 0.860000 0.000000 +vt 0.427341 0.225000 0.000000 +vt 0.391549 0.225000 0.000000 +vt 0.427341 0.225000 0.000000 +vt 0.427341 0.860000 0.000000 +vt 0.391549 0.860000 0.000000 +vt 0.391549 0.860000 0.000000 +vt 0.463134 0.225000 0.000000 +vt 0.427341 0.225000 0.000000 +vt 0.463134 0.225000 0.000000 +vt 0.463134 0.860000 0.000000 +vt 0.427341 0.860000 0.000000 +vt 0.427341 0.860000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.463134 0.225000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.498926 0.440000 0.000000 +vt 0.463134 0.440000 0.000000 +vt 0.463134 0.440000 0.000000 +vt 0.498926 0.860000 0.000000 +vt 0.463134 0.860000 0.000000 +vt 0.463134 0.860000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.498926 0.225000 0.000000 +vt 0.534718 0.225000 0.000000 +vt 0.534718 0.440000 0.000000 +vt 0.498926 0.440000 0.000000 +vt 0.534718 0.440000 0.000000 +vt 0.534718 0.860000 0.000000 +vt 0.498926 0.860000 0.000000 +vt 0.534718 0.860000 0.000000 +vt 0.534718 0.225000 0.000000 +vt 0.534718 0.225000 0.000000 +vt 0.570511 0.225000 0.000000 +vt 0.570511 0.860000 0.000000 +vt 0.534718 0.860000 0.000000 +vt 0.570511 0.860000 0.000000 +vt 0.570511 0.225000 0.000000 +vt 0.570511 0.225000 0.000000 +vt 0.606303 0.225000 0.000000 +vt 0.606303 0.860000 0.000000 +vt 0.570511 0.860000 0.000000 +vt 0.606303 0.860000 0.000000 +vt 0.606303 0.225000 0.000000 +vt 0.606303 0.225000 0.000000 +vt 0.642095 0.240000 0.000000 +vt 0.642095 0.240000 0.000000 +vt 0.642095 0.440000 0.000000 +vt 0.606303 0.440000 0.000000 +vt 0.642095 0.440000 0.000000 +vt 0.642095 0.860000 0.000000 +vt 0.606303 0.860000 0.000000 +vt 0.642095 0.860000 0.000000 +vt 0.677888 0.240000 0.000000 +vt 0.642095 0.240000 0.000000 +vt 0.677888 0.240000 0.000000 +vt 0.677888 0.440000 0.000000 +vt 0.642095 0.440000 0.000000 +vt 0.677888 0.440000 0.000000 +vt 0.677888 0.860000 0.000000 +vt 0.642095 0.860000 0.000000 +vt 0.677888 0.860000 0.000000 +vt 0.713680 0.240000 0.000000 +vt 0.677888 0.240000 0.000000 +vt 0.713680 0.240000 0.000000 +vt 0.713680 0.440000 0.000000 +vt 0.677888 0.440000 0.000000 +vt 0.713680 0.440000 0.000000 +vt 0.713680 0.860000 0.000000 +vt 0.677888 0.860000 0.000000 +vt 0.713680 0.860000 0.000000 +vt 0.749472 0.240000 0.000000 +vt 0.713680 0.240000 0.000000 +vt 0.749472 0.240000 0.000000 +vt 0.749472 0.440000 0.000000 +vt 0.713680 0.440000 0.000000 +vt 0.749472 0.440000 0.000000 +vt 0.749472 0.860000 0.000000 +vt 0.713680 0.860000 0.000000 +vt 0.749472 0.860000 0.000000 +vt 0.785264 0.240000 0.000000 +vt 0.749472 0.240000 0.000000 +vt 0.785264 0.240000 0.000000 +vt 0.785264 0.440000 0.000000 +vt 0.749472 0.440000 0.000000 +vt 0.785264 0.440000 0.000000 +vt 0.785264 0.860000 0.000000 +vt 0.749472 0.860000 0.000000 +vt 0.785264 0.860000 0.000000 +vt 0.821057 0.240000 0.000000 +vt 0.785264 0.240000 0.000000 +vt 0.821057 0.240000 0.000000 +vt 0.821057 0.440000 0.000000 +vt 0.785264 0.440000 0.000000 +vt 0.821057 0.440000 0.000000 +vt 0.821057 0.860000 0.000000 +vt 0.785264 0.860000 0.000000 +vt 0.821057 0.860000 0.000000 +vt 0.856849 0.225000 0.000000 +vt 0.821057 0.240000 0.000000 +vt 0.856849 0.440000 0.000000 +vt 0.821057 0.440000 0.000000 +vt 0.856849 0.440000 0.000000 +vt 0.856849 0.860000 0.000000 +vt 0.821057 0.860000 0.000000 +vt 0.856849 0.860000 0.000000 +vt 0.856849 0.225000 0.000000 +vt 0.856849 0.225000 0.000000 +vt 0.892641 0.225000 0.000000 +vt 0.892641 0.860000 0.000000 +vt 0.856849 0.860000 0.000000 +vt 0.892641 0.860000 0.000000 +vt 0.105211 0.225000 0.000000 +vt 0.105211 0.225000 0.000000 +vt 0.070255 0.240000 0.000000 +vt 0.070255 0.240000 0.000000 +vt 0.070985 0.440000 0.000000 +vt 0.105211 0.440000 0.000000 +vt 0.070985 0.440000 0.000000 +vt 0.072057 0.860000 0.000000 +vt 0.105211 0.860000 0.000000 +vt 0.072057 0.860000 0.000000 +vt 0.892641 0.225000 0.000000 +vt 0.892641 0.225000 0.000000 +vt 0.927597 0.240000 0.000000 +vt 0.927597 0.240000 0.000000 +vt 0.926867 0.440000 0.000000 +vt 0.926867 0.440000 0.000000 +vt 0.892641 0.440000 0.000000 +vt 0.925795 0.860000 0.000000 +vt 0.925795 0.860000 0.000000 +vt 0.892641 0.860000 0.000000 +# 1086 texture coords + +g arcs_03 +usemtl sp_00_luk_mali +f 151/151 152/152 153/153 154/154 +f 155/155 156/156 157/157 158/158 +f 801/801 802/802 159/159 +f 159/159 160/160 803/803 +f 161/161 162/162 163/163 164/164 +f 165/165 166/166 167/167 168/168 +f 169/169 170/170 171/171 172/172 +f 173/173 174/174 175/175 166/166 +f 166/166 175/175 176/176 167/167 +f 177/177 178/178 179/179 180/180 +f 180/180 179/179 181/181 182/182 +f 178/178 183/183 184/184 179/179 +f 179/179 184/184 185/185 181/181 +f 186/186 187/187 188/188 189/189 +f 190/190 191/191 192/192 193/193 +f 804/804 805/805 194/194 +f 194/194 195/195 806/806 +f 191/191 196/196 197/197 192/192 +f 807/807 808/808 198/198 +f 198/198 194/194 809/809 +f 199/199 200/200 201/201 202/202 +f 196/196 203/203 204/204 197/197 +f 201/201 200/200 205/205 206/206 +f 204/204 203/203 207/207 208/208 +f 208/208 207/207 209/209 210/210 +f 211/211 810/810 811/811 +f 812/812 212/212 211/211 +f 213/213 214/214 215/215 216/216 +f 210/210 209/209 217/217 218/218 +f 212/212 813/813 814/814 +f 815/815 219/219 212/212 +f 220/220 221/221 222/222 223/223 +f 224/224 220/220 223/223 225/225 +f 223/223 222/222 226/226 227/227 +f 225/225 223/223 227/227 228/228 +f 229/229 230/230 231/231 232/232 +f 233/233 234/234 235/235 236/236 +f 237/237 233/233 236/236 238/238 +f 238/238 236/236 239/239 240/240 +f 241/241 242/242 243/243 244/244 +f 245/245 246/246 247/247 248/248 +f 249/249 250/250 251/251 252/252 +f 253/253 816/816 817/817 +f 818/818 254/254 253/253 +f 158/158 255/255 256/256 155/155 +f 257/257 258/258 252/252 251/251 +f 259/259 260/260 261/261 262/262 +f 263/263 264/264 265/265 266/266 +f 267/267 819/819 820/820 +f 821/821 268/268 267/267 +f 269/269 270/270 271/271 272/272 +f 273/273 274/274 275/275 276/276 +f 277/277 278/278 279/279 280/280 +f 281/281 282/282 283/283 274/274 +f 284/284 281/281 274/274 273/273 +f 285/285 286/286 287/287 288/288 +f 289/289 285/285 288/288 290/290 +f 291/291 292/292 286/286 285/285 +f 293/293 291/291 285/285 289/289 +f 294/294 295/295 296/296 297/297 +f 298/298 299/299 300/300 301/301 +f 302/302 822/822 823/823 +f 824/824 303/303 302/302 +f 304/304 305/305 299/299 298/298 +f 306/306 825/825 826/826 +f 827/827 302/302 306/306 +f 307/307 308/308 309/309 310/310 +f 311/311 312/312 305/305 304/304 +f 313/313 308/308 307/307 314/314 +f 315/315 312/312 311/311 316/316 +f 317/317 315/315 316/316 318/318 +f 828/828 829/829 319/319 +f 319/319 320/320 830/830 +f 321/321 322/322 323/323 324/324 +f 325/325 317/317 318/318 326/326 +f 831/831 832/832 320/320 +f 320/320 327/327 833/833 +f 328/328 329/329 330/330 331/331 +f 331/331 330/330 332/332 333/333 +f 334/334 328/328 331/331 335/335 +f 335/335 331/331 333/333 336/336 +f 337/337 338/338 339/339 340/340 +f 341/341 342/342 343/343 344/344 +f 344/344 343/343 345/345 346/346 +f 347/347 344/344 346/346 348/348 +f 349/349 350/350 351/351 352/352 +f 353/353 354/354 355/355 356/356 +f 357/357 358/358 359/359 360/360 +f 834/834 835/835 361/361 +f 361/361 362/362 836/836 +f 363/363 364/364 266/266 265/265 +f 360/360 365/365 366/366 357/357 +f 367/367 368/368 837/837 +f 838/838 839/839 367/367 +f 154/154 153/153 369/369 370/370 +f 370/370 369/369 371/371 372/372 +f 372/372 371/371 156/156 155/155 +f 160/160 159/159 373/373 374/374 +f 374/374 373/373 375/375 376/376 +f 840/840 841/841 377/377 +f 377/377 378/378 842/842 +f 378/378 377/377 161/161 379/379 +f 379/379 161/161 164/164 380/380 +f 368/368 381/381 382/382 843/843 +f 152/152 844/844 383/383 153/153 +f 153/153 383/383 384/384 369/369 +f 369/369 384/384 385/385 371/371 +f 371/371 385/385 386/386 156/156 +f 156/156 386/386 387/387 157/157 +f 845/845 846/846 388/388 +f 388/388 159/159 847/847 +f 159/159 388/388 389/389 373/373 +f 373/373 389/389 390/390 375/375 +f 848/848 849/849 391/391 +f 391/391 377/377 850/850 +f 377/377 391/391 162/162 161/161 +f 381/381 392/392 393/393 382/382 +f 851/851 852/852 394/394 +f 394/394 383/383 853/853 +f 383/383 394/394 395/395 384/384 +f 384/384 395/395 396/396 385/385 +f 385/385 396/396 397/397 386/386 +f 386/386 397/397 398/398 387/387 +f 854/854 855/855 399/399 +f 399/399 388/388 856/856 +f 388/388 399/399 400/400 389/389 +f 389/389 400/400 401/401 390/390 +f 857/857 858/858 402/402 +f 402/402 391/391 859/859 +f 391/391 402/402 403/403 162/162 +f 162/162 403/403 404/404 163/163 +f 392/392 405/405 406/406 393/393 +f 860/860 861/861 407/407 +f 407/407 394/394 862/862 +f 394/394 407/407 408/408 395/395 +f 395/395 408/408 409/409 396/396 +f 396/396 409/409 165/165 397/397 +f 397/397 165/165 168/168 398/398 +f 863/863 864/864 410/410 +f 410/410 399/399 865/865 +f 399/399 410/410 411/411 400/400 +f 400/400 411/411 412/412 401/401 +f 866/866 867/867 413/413 +f 413/413 402/402 868/868 +f 402/402 413/413 414/414 403/403 +f 403/403 414/414 415/415 404/404 +f 405/405 416/416 417/417 406/406 +f 869/869 870/870 169/169 +f 169/169 407/407 871/871 +f 407/407 169/169 172/172 408/408 +f 408/408 172/172 173/173 409/409 +f 409/409 173/173 166/166 165/165 +f 872/872 873/873 418/418 +f 418/418 410/410 874/874 +f 410/410 418/418 419/419 411/411 +f 411/411 419/419 420/420 412/412 +f 875/875 876/876 421/421 +f 421/421 413/413 877/877 +f 413/413 421/421 422/422 414/414 +f 414/414 422/422 423/423 415/415 +f 416/416 424/424 425/425 417/417 +f 878/878 879/879 170/170 +f 170/170 169/169 880/880 +f 172/172 171/171 174/174 173/173 +f 881/881 882/882 426/426 +f 426/426 418/418 883/883 +f 418/418 426/426 427/427 419/419 +f 419/419 427/427 428/428 420/420 +f 884/884 885/885 177/177 +f 177/177 421/421 886/886 +f 421/421 177/177 180/180 422/422 +f 422/422 180/180 182/182 423/423 +f 424/424 429/429 430/430 425/425 +f 887/887 888/888 431/431 +f 431/431 170/170 889/889 +f 170/170 431/431 432/432 171/171 +f 171/171 432/432 433/433 174/174 +f 174/174 433/433 434/434 175/175 +f 175/175 434/434 435/435 176/176 +f 890/890 891/891 436/436 +f 436/436 426/426 892/892 +f 426/426 436/436 437/437 427/427 +f 427/427 437/437 438/438 428/428 +f 893/893 894/894 178/178 +f 178/178 177/177 895/895 +f 429/429 439/439 896/896 +f 897/897 430/430 429/429 +f 898/898 186/186 189/189 +f 189/189 431/431 899/899 +f 431/431 189/189 440/440 432/432 +f 432/432 440/440 441/441 433/433 +f 433/433 441/441 190/190 434/434 +f 434/434 190/190 193/193 435/435 +f 900/900 901/901 195/195 +f 195/195 436/436 902/902 +f 436/436 195/195 442/442 437/437 +f 437/437 442/442 443/443 438/438 +f 903/903 904/904 183/183 +f 183/183 178/178 905/905 +f 439/439 444/444 906/906 +f 907/907 908/908 439/439 +f 189/189 188/188 445/445 440/440 +f 440/440 445/445 446/446 441/441 +f 441/441 446/446 191/191 190/190 +f 195/195 194/194 447/447 442/442 +f 442/442 447/447 448/448 443/443 +f 909/909 910/910 449/449 +f 449/449 183/183 911/911 +f 183/183 449/449 450/450 184/184 +f 184/184 450/450 451/451 185/185 +f 444/444 452/452 912/912 +f 913/913 914/914 444/444 +f 187/187 199/199 202/202 188/188 +f 188/188 202/202 453/453 445/445 +f 445/445 453/453 454/454 446/446 +f 446/446 454/454 196/196 191/191 +f 194/194 198/198 455/455 447/447 +f 447/447 455/455 456/456 448/448 +f 915/915 916/916 457/457 +f 457/457 449/449 917/917 +f 449/449 457/457 458/458 450/450 +f 450/450 458/458 459/459 451/451 +f 452/452 460/460 918/918 +f 919/919 920/920 452/452 +f 202/202 201/201 461/461 453/453 +f 453/453 461/461 462/462 454/454 +f 454/454 462/462 203/203 196/196 +f 921/921 922/922 463/463 +f 463/463 198/198 923/923 +f 198/198 463/463 464/464 455/455 +f 455/455 464/464 465/465 456/456 +f 924/924 925/925 466/466 +f 466/466 457/457 926/926 +f 457/457 466/466 467/467 458/458 +f 458/458 467/467 468/468 459/459 +f 927/927 460/460 469/469 +f 469/469 928/928 929/929 +f 461/461 201/201 206/206 470/470 +f 462/462 461/461 470/470 471/471 +f 203/203 462/462 471/471 207/207 +f 463/463 930/930 931/931 +f 932/932 211/211 463/463 +f 464/464 463/463 211/211 472/472 +f 465/465 464/464 472/472 473/473 +f 466/466 933/933 934/934 +f 935/935 474/474 466/466 +f 467/467 466/466 474/474 475/475 +f 468/468 467/467 475/475 476/476 +f 936/936 469/469 477/477 +f 477/477 937/937 938/938 +f 206/206 205/205 214/214 213/213 +f 470/470 206/206 213/213 478/478 +f 471/471 470/470 478/478 479/479 +f 207/207 471/471 479/479 209/209 +f 472/472 211/211 212/212 480/480 +f 473/473 472/472 480/480 481/481 +f 474/474 939/939 940/940 +f 941/941 482/482 474/474 +f 475/475 474/474 482/482 483/483 +f 476/476 475/475 483/483 484/484 +f 942/942 477/477 485/485 +f 485/485 943/943 944/944 +f 478/478 213/213 216/216 486/486 +f 479/479 478/478 486/486 487/487 +f 209/209 479/479 487/487 217/217 +f 480/480 212/212 219/219 488/488 +f 481/481 480/480 488/488 489/489 +f 482/482 945/945 946/946 +f 947/947 221/221 482/482 +f 483/483 482/482 221/221 220/220 +f 484/484 483/483 220/220 224/224 +f 948/948 485/485 490/490 +f 490/490 491/491 949/949 +f 216/216 215/215 950/950 +f 951/951 492/492 216/216 +f 486/486 216/216 492/492 493/493 +f 487/487 486/486 493/493 494/494 +f 217/217 487/487 494/494 495/495 +f 218/218 217/217 495/495 496/496 +f 219/219 952/952 953/953 +f 954/954 497/497 219/219 +f 488/488 219/219 497/497 498/498 +f 489/489 488/488 498/498 499/499 +f 221/221 955/955 956/956 +f 957/957 222/222 221/221 +f 491/491 490/490 500/500 501/501 +f 492/492 958/958 959/959 +f 960/960 230/230 492/492 +f 493/493 492/492 230/230 229/229 +f 494/494 493/493 229/229 234/234 +f 495/495 494/494 234/234 233/233 +f 496/496 495/495 233/233 237/237 +f 497/497 961/961 962/962 +f 963/963 502/502 497/497 +f 498/498 497/497 502/502 503/503 +f 499/499 498/498 503/503 504/504 +f 222/222 964/964 965/965 +f 966/966 226/226 222/222 +f 501/501 500/500 505/505 506/506 +f 230/230 967/967 968/968 +f 969/969 231/231 230/230 +f 234/234 229/229 232/232 235/235 +f 502/502 970/970 971/971 +f 972/972 507/507 502/502 +f 503/503 502/502 507/507 508/508 +f 504/504 503/503 508/508 509/509 +f 226/226 973/973 974/974 +f 975/975 510/510 226/226 +f 227/227 226/226 510/510 511/511 +f 228/228 227/227 511/511 512/512 +f 506/506 505/505 513/513 514/514 +f 231/231 976/976 977/977 +f 978/978 515/515 231/231 +f 232/232 231/231 515/515 516/516 +f 235/235 232/232 516/516 517/517 +f 236/236 235/235 517/517 239/239 +f 507/507 979/979 980/980 +f 981/981 518/518 507/507 +f 508/508 507/507 518/518 519/519 +f 509/509 508/508 519/519 520/520 +f 510/510 982/982 983/983 +f 984/984 521/521 510/510 +f 511/511 510/510 521/521 522/522 +f 512/512 511/511 522/522 523/523 +f 514/514 513/513 524/524 525/525 +f 515/515 985/985 986/986 +f 987/987 526/526 515/515 +f 516/516 515/515 526/526 527/527 +f 517/517 516/516 527/527 528/528 +f 239/239 517/517 528/528 529/529 +f 240/240 239/239 529/529 530/530 +f 518/518 988/988 989/989 +f 990/990 531/531 518/518 +f 519/519 518/518 531/531 532/532 +f 520/520 519/519 532/532 533/533 +f 521/521 991/991 992/992 +f 993/993 534/534 521/521 +f 522/522 521/521 534/534 535/535 +f 523/523 522/522 535/535 536/536 +f 525/525 524/524 537/537 538/538 +f 526/526 994/994 995/995 +f 996/996 539/539 526/526 +f 527/527 526/526 539/539 540/540 +f 528/528 527/527 540/540 541/541 +f 529/529 528/528 541/541 542/542 +f 530/530 529/529 542/542 543/543 +f 531/531 997/997 998/998 +f 999/999 544/544 531/531 +f 532/532 531/531 544/544 545/545 +f 533/533 532/532 545/545 546/546 +f 534/534 1000/1000 1001/1001 +f 1002/1002 547/547 534/534 +f 535/535 534/534 547/547 242/242 +f 536/536 535/535 242/242 241/241 +f 538/538 537/537 548/548 1003/1003 +f 539/539 1004/1004 246/246 245/245 +f 540/540 539/539 245/245 549/549 +f 541/541 540/540 549/549 550/550 +f 542/542 541/541 550/550 250/250 +f 543/543 542/542 250/250 249/249 +f 544/544 1005/1005 1006/1006 +f 1007/1007 253/253 544/544 +f 545/545 544/544 253/253 551/551 +f 546/546 545/545 551/551 552/552 +f 547/547 1008/1008 1009/1009 +f 1010/1010 553/553 547/547 +f 242/242 547/547 553/553 243/243 +f 1011/1011 548/548 554/554 +f 554/554 1012/1012 1013/1013 +f 549/549 245/245 248/248 555/555 +f 550/550 549/549 555/555 556/556 +f 250/250 550/550 556/556 251/251 +f 551/551 253/253 254/254 557/557 +f 552/552 551/551 557/557 558/558 +f 553/553 1014/1014 1015/1015 +f 1016/1016 559/559 553/553 +f 243/243 553/553 559/559 560/560 +f 244/244 243/243 560/560 561/561 +f 1017/1017 562/562 563/563 +f 563/563 367/367 1018/1018 +f 154/154 564/564 1019/1019 +f 1020/1020 151/151 154/154 +f 370/370 565/565 564/564 154/154 +f 370/370 372/372 566/566 565/565 +f 372/372 155/155 256/256 566/566 +f 160/160 567/567 1021/1021 +f 1022/1022 1023/1023 160/160 +f 160/160 374/374 568/568 567/567 +f 376/376 569/569 568/568 374/374 +f 378/378 570/570 1024/1024 +f 1025/1025 1026/1026 378/378 +f 379/379 571/571 570/570 378/378 +f 380/380 572/572 571/571 379/379 +f 573/573 574/574 1027/1027 +f 1028/1028 554/554 573/573 +f 1029/1029 575/575 248/248 +f 248/248 247/247 1030/1030 +f 575/575 576/576 555/555 248/248 +f 577/577 556/556 555/555 576/576 +f 257/257 251/251 556/556 577/577 +f 1031/1031 578/578 254/254 +f 254/254 1032/1032 1033/1033 +f 579/579 557/557 254/254 578/578 +f 579/579 580/580 558/558 557/557 +f 1034/1034 581/581 559/559 +f 559/559 1035/1035 1036/1036 +f 581/581 582/582 560/560 559/559 +f 582/582 583/583 561/561 560/560 +f 1037/1037 584/584 585/585 +f 585/585 1038/1038 1039/1039 +f 586/586 259/259 262/262 587/587 +f 588/588 586/586 587/587 589/589 +f 264/264 588/588 589/589 265/265 +f 590/590 267/267 268/268 591/591 +f 592/592 590/590 591/591 593/593 +f 594/594 1040/1040 1041/1041 +f 1042/1042 595/595 594/594 +f 271/271 594/594 595/595 596/596 +f 272/272 271/271 596/596 597/597 +f 598/598 599/599 584/584 1043/1043 +f 600/600 1044/1044 260/260 259/259 +f 601/601 600/600 259/259 586/586 +f 602/602 601/601 586/586 588/588 +f 603/603 602/602 588/588 264/264 +f 604/604 603/603 264/264 263/263 +f 605/605 1045/1045 1046/1046 +f 1047/1047 267/267 605/605 +f 606/606 605/605 267/267 590/590 +f 607/607 606/606 590/590 592/592 +f 608/608 1048/1048 1049/1049 +f 1050/1050 594/594 608/608 +f 270/270 608/608 594/594 271/271 +f 609/609 610/610 599/599 598/598 +f 611/611 1051/1051 1052/1052 +f 1053/1053 600/600 611/611 +f 612/612 611/611 600/600 601/601 +f 613/613 612/612 601/601 602/602 +f 614/614 613/613 602/602 603/603 +f 615/615 614/614 603/603 604/604 +f 616/616 1054/1054 1055/1055 +f 1056/1056 605/605 616/616 +f 617/617 616/616 605/605 606/606 +f 618/618 617/617 606/606 607/607 +f 619/619 1057/1057 1058/1058 +f 1059/1059 608/608 619/619 +f 620/620 619/619 608/608 270/270 +f 621/621 620/620 270/270 269/269 +f 622/622 623/623 610/610 609/609 +f 624/624 1060/1060 1061/1061 +f 1062/1062 611/611 624/624 +f 625/625 624/624 611/611 612/612 +f 626/626 625/625 612/612 613/613 +f 275/275 626/626 613/613 614/614 +f 276/276 275/275 614/614 615/615 +f 627/627 1063/1063 1064/1064 +f 1065/1065 616/616 627/627 +f 628/628 627/627 616/616 617/617 +f 629/629 628/628 617/617 618/618 +f 630/630 1066/1066 1067/1067 +f 1068/1068 619/619 630/630 +f 631/631 630/630 619/619 620/620 +f 632/632 631/631 620/620 621/621 +f 633/633 634/634 623/623 622/622 +f 279/279 1069/1069 1070/1070 +f 1071/1071 624/624 279/279 +f 280/280 279/279 624/624 625/625 +f 283/283 280/280 625/625 626/626 +f 274/274 283/283 626/626 275/275 +f 635/635 1072/1072 1073/1073 +f 1074/1074 627/627 635/635 +f 636/636 635/635 627/627 628/628 +f 637/637 636/636 628/628 629/629 +f 638/638 1075/1075 1076/1076 +f 1077/1077 630/630 638/638 +f 639/639 638/638 630/630 631/631 +f 640/640 639/639 631/631 632/632 +f 641/641 642/642 634/634 633/633 +f 278/278 1078/1078 1079/1079 +f 1080/1080 279/279 278/278 +f 282/282 277/277 280/280 283/283 +f 643/643 1081/1081 1082/1082 +f 1083/1083 635/635 643/643 +f 644/644 643/643 635/635 636/636 +f 645/645 644/644 636/636 637/637 +f 287/287 1084/1084 1085/1085 +f 1086/1086 638/638 287/287 +f 288/288 287/287 638/638 639/639 +f 290/290 288/288 639/639 640/640 +f 646/646 647/647 642/642 641/641 +f 648/648 1087/1087 1088/1088 +f 1089/1089 278/278 648/648 +f 649/649 648/648 278/278 277/277 +f 650/650 649/649 277/277 282/282 +f 651/651 650/650 282/282 281/281 +f 652/652 651/651 281/281 284/284 +f 653/653 1090/1090 1091/1091 +f 1092/1092 643/643 653/653 +f 654/654 653/653 643/643 644/644 +f 655/655 654/654 644/644 645/645 +f 286/286 1093/1093 1094/1094 +f 1095/1095 287/287 286/286 +f 1096/1096 656/656 647/647 +f 647/647 646/646 1097/1097 +f 297/297 296/296 1098/1098 +f 1099/1099 648/648 297/297 +f 657/657 297/297 648/648 649/649 +f 658/658 657/657 649/649 650/650 +f 300/300 658/658 650/650 651/651 +f 301/301 300/300 651/651 652/652 +f 303/303 1100/1100 1101/1101 +f 1102/1102 653/653 303/303 +f 659/659 303/303 653/653 654/654 +f 660/660 659/659 654/654 655/655 +f 292/292 1103/1103 1104/1104 +f 1105/1105 286/286 292/292 +f 1106/1106 661/661 656/656 +f 656/656 1107/1107 1108/1108 +f 662/662 294/294 297/297 657/657 +f 663/663 662/662 657/657 658/658 +f 299/299 663/663 658/658 300/300 +f 664/664 302/302 303/303 659/659 +f 665/665 664/664 659/659 660/660 +f 666/666 1109/1109 1110/1110 +f 1111/1111 292/292 666/666 +f 667/667 666/666 292/292 291/291 +f 668/668 667/667 291/291 293/293 +f 1112/1112 669/669 661/661 +f 661/661 1113/1113 1114/1114 +f 310/310 309/309 295/295 294/294 +f 670/670 310/310 294/294 662/662 +f 671/671 670/670 662/662 663/663 +f 305/305 671/671 663/663 299/299 +f 672/672 306/306 302/302 664/664 +f 673/673 672/672 664/664 665/665 +f 674/674 1115/1115 1116/1116 +f 1117/1117 666/666 674/674 +f 675/675 674/674 666/666 667/667 +f 676/676 675/675 667/667 668/668 +f 1118/1118 677/677 669/669 +f 669/669 1119/1119 1120/1120 +f 678/678 307/307 310/310 670/670 +f 679/679 678/678 670/670 671/671 +f 312/312 679/679 671/671 305/305 +f 680/680 1121/1121 1122/1122 +f 1123/1123 306/306 680/680 +f 681/681 680/680 306/306 672/672 +f 682/682 681/681 672/672 673/673 +f 683/683 1124/1124 1125/1125 +f 1126/1126 674/674 683/683 +f 684/684 683/683 674/674 675/675 +f 685/685 684/684 675/675 676/676 +f 686/686 677/677 1127/1127 +f 1128/1128 1129/1129 686/686 +f 314/314 307/307 678/678 687/687 +f 687/687 678/678 679/679 688/688 +f 688/688 679/679 312/312 315/315 +f 1130/1130 1131/1131 680/680 +f 680/680 319/319 1132/1132 +f 319/319 680/680 681/681 689/689 +f 689/689 681/681 682/682 690/690 +f 1133/1133 1134/1134 683/683 +f 683/683 691/691 1135/1135 +f 691/691 683/683 684/684 692/692 +f 692/692 684/684 685/685 693/693 +f 694/694 686/686 1136/1136 +f 1137/1137 1138/1138 694/694 +f 322/322 313/313 314/314 323/323 +f 323/323 314/314 687/687 695/695 +f 695/695 687/687 688/688 696/696 +f 696/696 688/688 315/315 317/317 +f 320/320 319/319 689/689 697/697 +f 697/697 689/689 690/690 698/698 +f 1139/1139 1140/1140 691/691 +f 691/691 699/699 1141/1141 +f 699/699 691/691 692/692 700/700 +f 700/700 692/692 693/693 701/701 +f 702/702 694/694 1142/1142 +f 1143/1143 1144/1144 702/702 +f 324/324 323/323 695/695 703/703 +f 703/703 695/695 696/696 704/704 +f 704/704 696/696 317/317 325/325 +f 327/327 320/320 697/697 705/705 +f 705/705 697/697 698/698 706/706 +f 1145/1145 1146/1146 699/699 +f 699/699 329/329 1147/1147 +f 329/329 699/699 700/700 330/330 +f 330/330 700/700 701/701 332/332 +f 707/707 702/702 1148/1148 +f 1149/1149 708/708 707/707 +f 1150/1150 321/321 324/324 +f 324/324 709/709 1151/1151 +f 709/709 324/324 703/703 710/710 +f 710/710 703/703 704/704 711/711 +f 711/711 704/704 325/325 712/712 +f 712/712 325/325 326/326 713/713 +f 1152/1152 1153/1153 327/327 +f 327/327 714/714 1154/1154 +f 714/714 327/327 705/705 715/715 +f 715/715 705/705 706/706 716/716 +f 1155/1155 1156/1156 329/329 +f 329/329 328/328 1157/1157 +f 717/717 707/707 708/708 718/718 +f 1158/1158 1159/1159 709/709 +f 709/709 338/338 1160/1160 +f 338/338 709/709 710/710 339/339 +f 339/339 710/710 711/711 342/342 +f 342/342 711/711 712/712 343/343 +f 343/343 712/712 713/713 345/345 +f 1161/1161 1162/1162 714/714 +f 714/714 719/719 1163/1163 +f 719/719 714/714 715/715 720/720 +f 720/720 715/715 716/716 721/721 +f 1164/1164 1165/1165 328/328 +f 328/328 334/334 1166/1166 +f 722/722 717/717 718/718 723/723 +f 1167/1167 1168/1168 338/338 +f 338/338 337/337 1169/1169 +f 340/340 339/339 342/342 341/341 +f 1170/1170 1171/1171 719/719 +f 719/719 724/724 1172/1172 +f 724/724 719/719 720/720 725/725 +f 725/725 720/720 721/721 726/726 +f 1173/1173 1174/1174 334/334 +f 334/334 727/727 1175/1175 +f 727/727 334/334 335/335 728/728 +f 728/728 335/335 336/336 729/729 +f 730/730 722/722 723/723 731/731 +f 1176/1176 1177/1177 337/337 +f 337/337 732/732 1178/1178 +f 732/732 337/337 340/340 733/733 +f 733/733 340/340 341/341 734/734 +f 734/734 341/341 344/344 347/347 +f 1179/1179 1180/1180 724/724 +f 724/724 735/735 1181/1181 +f 735/735 724/724 725/725 736/736 +f 736/736 725/725 726/726 737/737 +f 1182/1182 1183/1183 727/727 +f 727/727 738/738 1184/1184 +f 738/738 727/727 728/728 739/739 +f 739/739 728/728 729/729 740/740 +f 741/741 730/730 731/731 742/742 +f 1185/1185 1186/1186 732/732 +f 732/732 743/743 1187/1187 +f 743/743 732/732 733/733 744/744 +f 744/744 733/733 734/734 745/745 +f 745/745 734/734 347/347 746/746 +f 746/746 347/347 348/348 747/747 +f 1188/1188 1189/1189 735/735 +f 735/735 748/748 1190/1190 +f 748/748 735/735 736/736 749/749 +f 749/749 736/736 737/737 750/750 +f 1191/1191 1192/1192 738/738 +f 738/738 751/751 1193/1193 +f 751/751 738/738 739/739 752/752 +f 752/752 739/739 740/740 753/753 +f 754/754 741/741 742/742 755/755 +f 1194/1194 1195/1195 743/743 +f 743/743 756/756 1196/1196 +f 756/756 743/743 744/744 757/757 +f 757/757 744/744 745/745 758/758 +f 758/758 745/745 746/746 759/759 +f 759/759 746/746 747/747 760/760 +f 1197/1197 1198/1198 748/748 +f 748/748 761/761 1199/1199 +f 761/761 748/748 749/749 762/762 +f 762/762 749/749 750/750 763/763 +f 1200/1200 1201/1201 751/751 +f 751/751 764/764 1202/1202 +f 764/764 751/751 752/752 350/350 +f 350/350 752/752 753/753 351/351 +f 765/765 754/754 755/755 1203/1203 +f 354/354 1204/1204 756/756 355/355 +f 355/355 756/756 757/757 766/766 +f 766/766 757/757 758/758 767/767 +f 767/767 758/758 759/759 358/358 +f 358/358 759/759 760/760 359/359 +f 1205/1205 1206/1206 761/761 +f 761/761 361/361 1207/1207 +f 361/361 761/761 762/762 768/768 +f 768/768 762/762 763/763 769/769 +f 1208/1208 1209/1209 764/764 +f 764/764 770/770 1210/1210 +f 770/770 764/764 350/350 349/349 +f 771/771 765/765 1211/1211 +f 1212/1212 1213/1213 771/771 +f 356/356 355/355 766/766 772/772 +f 772/772 766/766 767/767 773/773 +f 773/773 767/767 358/358 357/357 +f 362/362 361/361 768/768 774/774 +f 774/774 768/768 769/769 775/775 +f 1214/1214 1215/1215 770/770 +f 770/770 776/776 1216/1216 +f 776/776 770/770 349/349 777/777 +f 777/777 349/349 352/352 778/778 +f 779/779 780/780 1217/1217 +f 1218/1218 585/585 779/779 +f 1219/1219 781/781 262/262 +f 262/262 261/261 1220/1220 +f 781/781 782/782 587/587 262/262 +f 783/783 589/589 587/587 782/782 +f 363/363 265/265 589/589 783/783 +f 1221/1221 784/784 268/268 +f 268/268 1222/1222 1223/1223 +f 785/785 591/591 268/268 784/784 +f 785/785 786/786 593/593 591/591 +f 1224/1224 787/787 595/595 +f 595/595 1225/1225 1226/1226 +f 787/787 788/788 596/596 595/595 +f 788/788 789/789 597/597 596/596 +f 1227/1227 790/790 791/791 +f 791/791 771/771 1228/1228 +f 356/356 792/792 1229/1229 +f 1230/1230 353/353 356/356 +f 772/772 793/793 792/792 356/356 +f 772/772 773/773 794/794 793/793 +f 773/773 357/357 366/366 794/794 +f 362/362 795/795 1231/1231 +f 1232/1232 1233/1233 362/362 +f 362/362 774/774 796/796 795/795 +f 775/775 797/797 796/796 774/774 +f 776/776 798/798 1234/1234 +f 1235/1235 1236/1236 776/776 +f 777/777 799/799 798/798 776/776 +f 778/778 800/800 799/799 777/777 +# 428 polygons - 296 triangles \ No newline at end of file From e65166fa58145b7cd8dd79b66aa599449b0a3379 Mon Sep 17 00:00:00 2001 From: Frederic Freyer Date: Tue, 19 Nov 2024 15:06:12 +0100 Subject: [PATCH 20/22] bump MeshIO version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 302d0ae..c7a9bb3 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "MeshIO" uuid = "7269a6da-0436-5bbc-96c2-40638cbb6118" author = "Simon Danisch" -version = "0.4.13" +version = "0.5.0" [deps] ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" From b65be9e9b4dd8f8d869bb850431138c2eacff9f4 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 19 Nov 2024 16:04:21 +0100 Subject: [PATCH 21/22] update readme --- README.md | 58 +++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index 21b7a46..686ef54 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![codecov.io](http://codecov.io/github/JuliaIO/MeshIO.jl/coverage.svg?branch=master)](http://codecov.io/github/JuliaIO/MeshIO.jl?branch=master) [![Coverage Status](https://coveralls.io/repos/JuliaIO/MeshIO.jl/badge.svg?branch=master&service=github)](https://coveralls.io/github/JuliaIO/MeshIO.jl?branch=master) -This package supports loading 3D model file formats: `obj`, `stl`, `ply`, `off` and `2DM`. +This package supports loading 3D model file formats: `obj`, `stl`, `ply`, `off`, `msh` and `2DM`. More 3D model formats will be supported in the future. ## Installation @@ -22,49 +22,35 @@ This means loading a mesh is as simple as this: using FileIO mesh = load("path/to/mesh.obj") ``` +The result will usually be a [GeometryBasics](https://github.com/JuliaGeometry/GeometryBasics.jl) `Mesh`. +The exception are `obj` files with non-vertex data such as material data or "group" tags, which return a `MetaMesh`. + Displaying a mesh can be achieved with [Makie](https://github.com/JuliaPlots/Makie.jl). Functions for mesh manipulation can be found in [JuliaGeometry](https://github.com/JuliaGeometry) ## Additional Information -MeshIO now has the HomogenousMesh type. Name is still not settled, but it's supposed to be a dense mesh with all attributes either having the length of one (constant over the whole mesh) or the same length (per vertex). -This meshtype holds a large variability for all the different attribute mixtures that I've encountered while trying to visualize things over at GLVisualize. This is the best type I've found so far to encode this large variability, without an explosion of functions. - -The focus is on conversion between different mesh types and creation of different mesh types. -This has led to some odd seeming design choices. -First, you can get an attribute via `decompose(::Type{AttributeType}, ::Mesh)`. -This will try to get this attribute, and if it has the wrong type try to convert it, or if it is not available try to create it. -So `decompose(Point3{Float32}, mesh)` on a mesh with vertices of type `Point3{Float64}` will return a vector of type `Point3{Float32}`. -Similarly, if you call `decompose(Normal{3, Float32}, mesh)` but the mesh doesn't have normals, it will call the function `normals(mesh.vertices, mesh.faces, Normal{3, Float32}`, which will create the normals for the mesh. -As most attributes are independent, this enables us to easily create all kinds of conversions. -Also, I can define `decompose` for arbitrary geometric types. -`decompose{T}(Point3{T}, r::Rectangle)` can actually return the needed vertices for a rectangle. -This together with `convert` enables us to create mesh primitives like this: -```Julia -MeshType(Cube(...)) -MeshType(Sphere(...)) -MeshType(Volume, 0.4f0) #0.4f0 => isovalue -``` +### Usage -Similarly, I can pass a meshtype to an IO function, which then parses only the attributes that I really need. -So passing `Mesh{Point3{Float32}, Face3{UInt32}}` to the obj importer will skip normals, uv coordinates etc, and automatically converts the given attributes to the right number type. +The GeometryBasics `Mesh` supports vertex attributes with different lengths which get addressed by different faces (as of 0.5). +As such MeshIO makes no effort to convert vertex attributes to a common length, indexed by one set of faces. +If you need a single set of faces, e.g. for rendering, you can use `new_mesh = GeometryBasics.expand_faceviews(mesh)` to generate a fitting mesh. -To put this one level further, the `Face` type has the index offset relative to Julia's indexing as a parameter (e.g. `Face3{T, 0}` is 1 indexed). Also, you can index into an array with this face type, and it will convert the indexes correctly while accessing the array. So something like this always works, independent of the underlying index offset: -```Julia -v1, v2, v3 = vertices[face] +The GeometryBasics `Mesh` allows for different element types for coordinates, normals, faces, etc. +These can set when loading a mesh using keyword arguments: +```julia +load(filename; pointtype = Point3f, uvtype = Vec2f, facetype = GLTriangleFace, normaltype = Vec3f) ``` -Also, the importer is sensitive to this, so if you always want to work with 0-indexed faces (like it makes sense for opengl based visualizations), you can parse the mesh already as an 0-indexed mesh, by just defining the mesh format to use `Face3{T, -1}`. (only the OBJ importer yet) +Note that not every file format supports normals and uvs (texture coordinates) and thus some loaders don't accept `uvtype` and/or `normaltype`. -Small example to demonstrate the advantage for IO: -```Julia -#Export takes any mesh -function write{M <: Mesh}(msh::M, fn::File{:ply_binary}) - # even if the native mesh format doesn't have an array of dense points or faces, the correct ones will - # now be created, or converted: - vts = decompose(Point3{Float32}, msh) # I know ply_binary needs Point3{Float32} - fcs = decompose(Face3{Int32, -1}, msh) # And 0 indexed Int32 faces. - #write code... -end - ``` +The facetypes from GeometryBasics support 0 and 1-based indexing using `OffsetInteger`s. +For example `GLTriangleFace` is an alias for `NgonFace{3, OffsetInteger{-1, UInt32}}`, i.e. a face containing 3 indices offset from 1-based indexing by `-1`. +The raw data in a `GLTriangleFace` is 0-based so that it can be uploaded directly in a Graphics API. +In Julia code it gets converted back to a 1-based Int, so that it can be used as is. + +### Extending MeshIO +To implement a new file format you need to add the appropriate `load()` and `save()` methods. +You also need to register the file format with [FileIO](https://juliaio.github.io/FileIO.jl/stable/registering/) +For saving it may be useful to know that you can convert vertex data to specific types using the [decompose interface](https://juliageometry.github.io/GeometryBasics.jl/stable/decomposition/). From 8666d914e1d69e2f236b54f50d4239d3332de623 Mon Sep 17 00:00:00 2001 From: ffreyer Date: Tue, 19 Nov 2024 16:23:45 +0100 Subject: [PATCH 22/22] fix position-normal faces, cleanup material warning --- src/io/obj.jl | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/io/obj.jl b/src/io/obj.jl index 4c7dfb5..a6ec285 100644 --- a/src/io/obj.jl +++ b/src/io/obj.jl @@ -63,15 +63,17 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, if any(x-> occursin("//", x), lines) fs = process_face_normal(lines) + append!(f_uv_n_faces[1], triangulated_faces(facetype, getindex.(fs, 1))) + append!(f_uv_n_faces[3], triangulated_faces(facetype, getindex.(fs, 2))) elseif any(x-> occursin("/", x), lines) fs = process_face_uv_or_normal(lines) + for i = 1:length(first(fs)) + append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i))) + end else append!(faces, triangulated_faces(facetype, lines)) continue end - for i = 1:length(first(fs)) - append!(f_uv_n_faces[i], triangulated_faces(facetype, getindex.(fs, i))) - end elseif "s" == command # Blender sets this just before faces shadings = get!(() -> Dict{Int, Bool}(), group_meta, :shading) @@ -84,7 +86,7 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, elseif "g" == command groups = get!(() -> Dict{Int, String}(), group_meta, :groups) groups[length(faces)+1] = join(lines, ' ') - + elseif "mtllib" == command push!(mtllibs, join(lines, ' ')) @@ -105,26 +107,26 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, if !isempty(f_uv_n_faces[2]) && (f_uv_n_faces[2] != faces) uv = FaceView(uv, f_uv_n_faces[2]) end - + if !isempty(f_uv_n_faces[3]) && (f_uv_n_faces[3] != faces) v_normals = FaceView(v_normals, f_uv_n_faces[3]) end mesh = GeometryBasics.mesh( - points, faces, facetype = facetype; - uv = isempty(uv) ? nothing : uv, + points, faces, facetype = facetype; + uv = isempty(uv) ? nothing : uv, normal = isempty(v_normals) ? nothing : v_normals ) if !isempty(group_meta) - + # Find all the starting indices used across objects, groups, shadings, materials starts_set = Set{Int}() for meta in values(group_meta) union!(starts_set, keys(meta)) end starts_vec = sort!(collect(starts_set)) - + # generate views resize!(mesh.views, length(starts_vec)) for i in 1:length(starts_vec)-1 @@ -143,6 +145,10 @@ function load(fn::File{format"OBJ"}; facetype=GLTriangleFace, end end + if isempty(mtllibs) && !haskey(group_meta, :material_names) + return MetaMesh(mesh, metadata) + end + # Load material files materials = Dict{String, Dict{String, Any}}() path = joinpath(splitpath(FileIO.filename(fn))[1:end-1]...) @@ -223,26 +229,26 @@ end function _load_mtl!(materials::Dict{String, Dict{String, Any}}, filename::String) endswith(filename, ".mtl") || error("Material Template Library $filename must be a .mtl file.") - - + + name_lookup = Dict( "Ka" => "ambient", "Kd" => "diffuse", "Ks" => "specular", "Ns" => "shininess", "d" => "alpha", "Tr" => "transmission", # 1 - alpha "Ni" => "refractive index", "illum" => "illumination model", # PBR - "Pr" => "roughness", "Pm" => "metallic", "Ps" => "sheen", - "Pc" => "clearcoat thickness", "Pcr" => "clearcoat roughness", - "Ke" => "emissive", "aniso" => "anisotropy", - "anisor" => "anisotropy rotation", + "Pr" => "roughness", "Pm" => "metallic", "Ps" => "sheen", + "Pc" => "clearcoat thickness", "Pcr" => "clearcoat roughness", + "Ke" => "emissive", "aniso" => "anisotropy", + "anisor" => "anisotropy rotation", "Tf" => "transmission filter", # texture maps - "map_Ka" => "ambient map", "map_Kd" => "diffuse map", - "map_Ks" => "specular map", "map_Ns" => "shininess map", + "map_Ka" => "ambient map", "map_Kd" => "diffuse map", + "map_Ks" => "specular map", "map_Ns" => "shininess map", "map_d" => "alpha map", "map_Tr" => "transmission map", "map_bump" => "bump map", "bump" => "bump map", "disp" => "displacement map", "decal" => "decal map", "refl" => "reflection map", "norm" => "normal map", - "map_Pr" => "roughness map", "map_Pm" => "metallic map", + "map_Pr" => "roughness map", "map_Pm" => "metallic map", "map_Ps" => "sheen map", "map_Ke" => "emissive map", "map_RMA" => "roughness metalness occlusion map", "map_ORM" => "occlusion roughness metalness map", @@ -346,7 +352,7 @@ function parse_texture_info(parent_path::String, lines::Vector{SubString{String} elseif command == "boost" || command == "bm" output[name_lookup[command]] = parse(Float32, lines[idx+1]) idx += 2 - + elseif command == "mm" output["brightness"] = parse(Float32, lines[idx+1]) output["contrast"] = parse(Float32, lines[idx+2])