From 7e0e9eba9789ff80743dc68cae98db6f400a834e Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Tue, 13 Jun 2023 00:37:07 +0800 Subject: [PATCH 01/18] WIP: Normal mapping and vertex normal --- parsers/obj_desc.py | 11 +++++++++-- parsers/obj_loader.py | 21 ++++++++++++--------- parsers/xml_parser.py | 17 ++++++++++++++--- renderer/bdpt.py | 2 +- renderer/vanilla_renderer.py | 2 +- renderer/vpt.py | 2 +- tracer/path_tracer.py | 6 +++--- tracer/tracer_base.py | 2 +- 8 files changed, 42 insertions(+), 21 deletions(-) diff --git a/parsers/obj_desc.py b/parsers/obj_desc.py index 6faa16b..3cda57a 100644 --- a/parsers/obj_desc.py +++ b/parsers/obj_desc.py @@ -27,8 +27,12 @@ def get_aabb(meshes: Arr, _type: int = 0) -> Arr: class ObjDescriptor: def __init__( - self, meshes, normals, bsdf, uv_coords = None, - texture = None, R = None, t = None, emit_id = -1, _type = 0 + self, meshes, normals, bsdf, + vert_normal = None, + uv_coords = None, + texture = None, + R = None, t = None, + emit_id = -1, _type = 0 ): """ Inputs are objects on which transformations have been applied already @@ -39,10 +43,13 @@ def __init__( self.meshes = meshes self.uv_coords = uv_coords self.normals = normals + self.vns = vert_normal # TODO: maybe we should work on shading normals in the future self.R = R self.t = t self.bsdf = bsdf # object can have BSDF (BRDF + BTDF) + + # Texture includes all texture mappings self.texture = texture self.aabb = get_aabb(meshes, _type) # of shape (2, 3) self.emitter_ref_id = emit_id diff --git a/parsers/obj_loader.py b/parsers/obj_loader.py index 144eaa2..7236db7 100644 --- a/parsers/obj_loader.py +++ b/parsers/obj_loader.py @@ -34,6 +34,7 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): break if material is not None: vert_type = material.vertex_format + print(vert_type) if "T" not in vert_type: if verbose: CONSOLE.log(f"[blue]Attention: Object contains no uv-coordinates for vtype '{vert_type}'") @@ -41,9 +42,9 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): start_dim = 0 dim_num = sum([int(part[1:]) for part in all_parts]) all_data = np.float32(material.vertices).reshape(-1, dim_num) - mesh_faces = None - uv_coords = None - normals = None + mesh_faces = None + vert_normal = None + uv_coords = None for part in all_parts: if part.startswith("T"): uv_coords = all_data[:, start_dim:start_dim+2] @@ -54,6 +55,8 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): uv_coords = uv_coords.reshape(-1, 3, 2) elif part.startswith("V"): mesh_faces = np.float32(all_data[:, start_dim:start_dim+3]).reshape(-1, 3, 3) + elif part.startswith("N"): + vert_normal = np.float32(all_data[:, start_dim:start_dim+3]).reshape(-1, 3, 3) start_dim += int(part[1:]) assert mesh_faces is not None # we directly use the vertices loaded, so this can not be empty @@ -62,15 +65,15 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): # so uv-coordinates are ordered too # vertices shape: (N_faces, 3, 3), uv_coords shape: (N_faces, 3, 2) - if normals is None: # normal is not computed in obj - dp1 = mesh_faces[:, 1, :] - mesh_faces[:, 0, :] - dp2 = mesh_faces[:, 2, :] - mesh_faces[:, 1, :] - normals = np.cross(dp1, dp2) - normals /= np.linalg.norm(normals, axis = -1, keepdims = True) + # calculate geometrical normal + dp1 = mesh_faces[:, 1, :] - mesh_faces[:, 0, :] + dp2 = mesh_faces[:, 2, :] - mesh_faces[:, 1, :] + normals = np.cross(dp1, dp2) + normals /= np.linalg.norm(normals, axis = -1, keepdims = True) if verbose: CONSOLE.log(f"Mesh loaded from '{path}', output shape: [blue]{mesh_faces.shape}[/blue]") - return mesh_faces, normals, uv_coords + return mesh_faces, normals, vert_normal, uv_coords else: raise ValueError("This wavefront onject file has no material but it is required.") diff --git a/parsers/xml_parser.py b/parsers/xml_parser.py index 169efd2..e045d7c 100644 --- a/parsers/xml_parser.py +++ b/parsers/xml_parser.py @@ -90,11 +90,12 @@ def parse_wavefront( # We need to calculate surface area of the object mesh first (asuming each triangle has similar area) attached_area_dict = {} for elem in obj_list: - uvs, trans_r, trans_t = None, None, None # uv_coordinates and transform + vns, uvs, trans_r, trans_t = None, None, None, None # uv_coordinates and transform obj_type = 0 if elem.get("type") == "obj": filepath_child = elem.find("string") - meshes, normals, uvs = extract_obj_info(os.path.join(directory, filepath_child.get("value"))) + # get mesh / geometrical normal / shading normal / uv coords for texture + meshes, normals, vns, uvs = extract_obj_info(os.path.join(directory, filepath_child.get("value"))) transform_child = elem.find("transform") if transform_child is not None: trans_r, trans_t = transform_parse(transform_child) @@ -119,7 +120,7 @@ def parse_wavefront( if bsdf_item is None: raise ValueError("Object should be attached with a BSDF for now since no default one implemented yet.") - all_objs.append(ObjDescriptor(meshes, normals, bsdf_item, uvs, texture, trans_r, trans_t, emit_ref_id, obj_type)) + all_objs.append(ObjDescriptor(meshes, normals, bsdf_item, vns, uvs, texture, trans_r, trans_t, emit_ref_id, obj_type)) return all_objs, attached_area_dict def parse_bxdf(bxdf_list: List[xet.Element]): @@ -201,6 +202,16 @@ def scene_parsing(directory: str, file: str): emitter_dict = parse_emitters(emitter_nodes) bsdf_dict = parse_bxdf(bxdf_nodes) teximg, textures = parse_texture(texture_nodes) + """ Texture mapping should be updateded (FIXME): + (1) . Now for each object, there can only be one ref for each type of reference + But TODO: texture needs more that one (albedo map, normal map, bump map, roughness map), for other mappings + I do not want to implement them. Therefore, 1-to-many mapping should be correctly established + (2) Loading from python to Taichi (for different kinds of mapping) + Each mapping might needs a different packing, therefore we need different image packaging and texture info block + For normal mapping, non-bidirectional renderers will be simple but not for BDPT + roughness is of lower priority + (3) Speed up python->taichi conversion + """ meshes, area_lut = parse_wavefront(directory, shape_nodes, bsdf_dict, emitter_dict, textures) configs = parse_global_sensor(sensor_node) configs['world'] = parse_world(world_node) diff --git a/renderer/bdpt.py b/renderer/bdpt.py index ad21211..1a658ce 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -263,7 +263,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: is_delta = (not is_mi) and self.is_delta(obj_id) bool_bits = BDPT.get_bool(d_delta = is_delta, is_area = (hit_light >= 0), in_fspace = in_free_space, is_delta = is_delta) - tex = self.get_uv_color(obj_id, prim_id, u_coord, v_coord) + tex = self.get_uv_item(self.textures, self.texture_img, obj_id, prim_id, u_coord, v_coord) vertex_args = {"_type": ti.select(is_mi, VERTEX_MEDIUM, VERTEX_SURFACE), "obj_id": obj_id, "emit_id": hit_light, "bool_bits": bool_bits, "pdf_fwd": pdf_fwd, "time": acc_time, "pos": hit_point, "normal": ti.select(is_mi, ZERO_V3, normal), "ray_in": ray_d, "beta": throughput, "tex": tex diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index 0204d4f..2c66f15 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -55,7 +55,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex = self.get_uv_color(obj_id, prim_id, u_coord, v_coord) + tex = self.get_uv_item(self.textures, self.texture_img, obj_id, prim_id, u_coord, v_coord) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) diff --git a/renderer/vpt.py b/renderer/vpt.py index 914f7e8..d113e70 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -162,7 +162,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex = self.get_uv_color(obj_id, prim_id, u_coord, v_coord) + tex = self.get_uv_item(self.textures, self.texture_img, obj_id, prim_id, u_coord, v_coord) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 349df2e..f435938 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -226,16 +226,16 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): self.src_field[emitter_ref_id].obj_ref_id = i @ti.func - def get_uv_color(self, obj_id: int, prim_id: int, u: float, v: float): + def get_uv_item(self, textures: ti.template(), tex_img: ti.template(), obj_id: int, prim_id: int, u: float, v: float): """ Convert primitive local UV to the global UV coord for an object """ color = INVALID - has_texture = self.textures[obj_id].type > -255 + has_texture = textures[obj_id].type > -255 if has_texture: is_sphere = self.obj_info[obj_id, 2] if is_sphere == 0: # not a sphere u, v = self.uv_coords[prim_id, 1] * u + self.uv_coords[prim_id, 2] * v + \ self.uv_coords[prim_id, 0] * (1. - u - v) - color = self.textures[obj_id].query(self.texture_img, u, v) + color = textures[obj_id].query(tex_img, u, v) return color @ti.func diff --git a/tracer/tracer_base.py b/tracer/tracer_base.py index 409a94f..8e1ce44 100644 --- a/tracer/tracer_base.py +++ b/tracer/tracer_base.py @@ -189,7 +189,7 @@ def ray_intersect(self, ray, start_p, min_depth = -1.0): coord_v = tm.acos(normal[2]) * INV_PI else: normal = self.normals[prm_id] - return (obj_id, normal, min_depth, coord_u, coord_v) + return (obj_id, normal, min_depth, prm_id, coord_u, coord_v) @ti.func def does_intersect(self, ray, start_p, min_depth = -1.0): From 347b0cda7511d75fc310a0677597c1a6e5ebe7d6 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Thu, 15 Jun 2023 00:32:24 +0800 Subject: [PATCH 02/18] Various texture mapping parsing completed. --- parsers/obj_desc.py | 4 +- parsers/texture_packing.py | 3 +- parsers/xml_parser.py | 51 +- renderer/bdpt.py | 2 +- renderer/vanilla_renderer.py | 2 +- renderer/vpt.py | 2 +- scenes/cbox/cbox-vn.xml | 133 ++ scenes/meshes/cornell/flat-ball.obj | 2535 +++++++++++++++++++++++++ scenes/meshes/cornell/smooth-ball.obj | 2486 ++++++++++++++++++++++++ tracer/path_tracer.py | 48 +- 10 files changed, 5226 insertions(+), 40 deletions(-) create mode 100755 scenes/cbox/cbox-vn.xml create mode 100644 scenes/meshes/cornell/flat-ball.obj create mode 100644 scenes/meshes/cornell/smooth-ball.obj diff --git a/parsers/obj_desc.py b/parsers/obj_desc.py index 3cda57a..aab727e 100644 --- a/parsers/obj_desc.py +++ b/parsers/obj_desc.py @@ -30,7 +30,7 @@ def __init__( self, meshes, normals, bsdf, vert_normal = None, uv_coords = None, - texture = None, + texture_group = None, R = None, t = None, emit_id = -1, _type = 0 ): @@ -50,7 +50,7 @@ def __init__( self.bsdf = bsdf # object can have BSDF (BRDF + BTDF) # Texture includes all texture mappings - self.texture = texture + self.texture_group = texture_group self.aabb = get_aabb(meshes, _type) # of shape (2, 3) self.emitter_ref_id = emit_id self.type = _type diff --git a/parsers/texture_packing.py b/parsers/texture_packing.py index 0117a00..802e8ff 100644 --- a/parsers/texture_packing.py +++ b/parsers/texture_packing.py @@ -24,12 +24,13 @@ from matplotlib.patches import Rectangle -SIZE2USE = [4096, 3072, 2048, 1024] +SIZE2USE = [3072, 2048, 1024, 720] __all__ = ("image_packer") @timing() def image_packer(textures: List[Texture_np]) -> Tuple[np.ndarray, List[Texture_np]]: + # TODO: Check this logic? this seems strange starting_point = 3 total_size = 0 rects = [] diff --git a/parsers/xml_parser.py b/parsers/xml_parser.py index e045d7c..e4c1491 100644 --- a/parsers/xml_parser.py +++ b/parsers/xml_parser.py @@ -82,9 +82,7 @@ def parse_emitters(em_elem: list): def parse_wavefront( directory: str, obj_list: List[xet.Element], bsdf_dict: dict, emitter_dict: dict, texture_dict: List[Texture_np]) -> List[Arr]: - """ - Parsing wavefront obj file (filename) from list of xml nodes - """ + """ Parsing wavefront obj file (filename) from list of xml nodes """ all_objs = [] # Some emitters will be attached to objects, to sample the object-attached emitters # We need to calculate surface area of the object mesh first (asuming each triangle has similar area) @@ -103,10 +101,13 @@ def parse_wavefront( else: # CURRENTLY, only sphere is supported meshes, normals = parse_sphere_element(elem) obj_type = 1 - ref_childs = elem.findall("ref") - bsdf_item = None - texture = None - emit_ref_id = -1 + ref_childs = elem.findall("ref") + bsdf_item = None + texture_group = {"albedo": None, "normal": None, "bump": None, "roughness": None} + emit_ref_id = -1 + + # Currently, texture (groups) and object form bi-jection, since this way is simpler to implement + # and can avoid id look up (memory ops might be very slow) for ref_child in ref_childs: ref_type = ref_child.get("type") ref_id = ref_child.get("id") @@ -116,11 +117,21 @@ def parse_wavefront( emit_ref_id = emitter_dict[ref_id] attached_area_dict[emit_ref_id] = calculate_surface_area(meshes, obj_type) elif ref_type == "texture": - texture = texture_dict[ref_id] + ref_tag = ref_child.get("tag", None) + if ref_tag == None: + ref_tag = "albedo" + CONSOLE.log(f"[yellow]Warning: BXDF[/yellow] Texture ref_id {ref_id} has no tag. Set default as 'albedo'.") + elif ref_tag not in texture_group: + ref_tag = "albedo" + CONSOLE.log(f"[yellow]Warning: BXDF[/yellow] Texture ref_tag {ref_tag} not supported. Set default as 'albedo'.") + # make sure texture group has corresponding tag + if texture_dict[ref_tag] is None or ref_id not in texture_dict[ref_tag]: + raise KeyError(f"Texture id '{ref_id}' does not have tag '{ref_tag}' mapping, check if it is from other groups.") + texture_group[ref_tag] = texture_dict[ref_tag][ref_id] if bsdf_item is None: raise ValueError("Object should be attached with a BSDF for now since no default one implemented yet.") - all_objs.append(ObjDescriptor(meshes, normals, bsdf_item, vns, uvs, texture, trans_r, trans_t, emit_ref_id, obj_type)) + all_objs.append(ObjDescriptor(meshes, normals, bsdf_item, vns, uvs, texture_group, trans_r, trans_t, emit_ref_id, obj_type)) return all_objs, attached_area_dict def parse_bxdf(bxdf_list: List[xet.Element]): @@ -143,15 +154,25 @@ def parse_bxdf(bxdf_list: List[xet.Element]): def parse_texture(texture_list: List[xet.Element]): """ Parsing Textures - return List of Texture_np + return Dict of Texture_np, containing four different types of mapping """ if len(texture_list) == 0: return None, None - textures = [] + textures = {"albedo": [], "normal": [], "bump": [], "roughness": []} for texture in texture_list: - textures.append(Texture_np(texture)) + map_type = texture.get("tag", "albedo") + textures[map_type].append(Texture_np(texture)) # Do texture packing - return image_packer(textures) + packed_textures = {} + packed_imgs = {} + for key, value in textures.items(): + if len(value) == 0: + tex_img, tex_info = None, None + else: + tex_img, tex_info = image_packer(value) + packed_imgs[key] = tex_img + packed_textures[key] = tex_info + return packed_imgs, packed_textures def parse_world(world_elem: xet.Element): world = World_np(world_elem) @@ -201,7 +222,7 @@ def scene_parsing(directory: str, file: str): emitter_configs, \ emitter_dict = parse_emitters(emitter_nodes) bsdf_dict = parse_bxdf(bxdf_nodes) - teximg, textures = parse_texture(texture_nodes) + teximgs, textures = parse_texture(texture_nodes) """ Texture mapping should be updateded (FIXME): (1) . Now for each object, there can only be one ref for each type of reference But TODO: texture needs more that one (albedo map, normal map, bump map, roughness map), for other mappings @@ -215,7 +236,7 @@ def scene_parsing(directory: str, file: str): meshes, area_lut = parse_wavefront(directory, shape_nodes, bsdf_dict, emitter_dict, textures) configs = parse_global_sensor(sensor_node) configs['world'] = parse_world(world_node) - configs['packed_texture'] = teximg + configs['packed_textures'] = teximgs emitter_configs = update_emitter_config(emitter_configs, area_lut) return emitter_configs, meshes, configs diff --git a/renderer/bdpt.py b/renderer/bdpt.py index 1a658ce..d5bef15 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -263,7 +263,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: is_delta = (not is_mi) and self.is_delta(obj_id) bool_bits = BDPT.get_bool(d_delta = is_delta, is_area = (hit_light >= 0), in_fspace = in_free_space, is_delta = is_delta) - tex = self.get_uv_item(self.textures, self.texture_img, obj_id, prim_id, u_coord, v_coord) + tex = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) vertex_args = {"_type": ti.select(is_mi, VERTEX_MEDIUM, VERTEX_SURFACE), "obj_id": obj_id, "emit_id": hit_light, "bool_bits": bool_bits, "pdf_fwd": pdf_fwd, "time": acc_time, "pos": hit_point, "normal": ti.select(is_mi, ZERO_V3, normal), "ray_in": ray_d, "beta": throughput, "tex": tex diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index 2c66f15..f92cae4 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -55,7 +55,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex = self.get_uv_item(self.textures, self.texture_img, obj_id, prim_id, u_coord, v_coord) + tex = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) diff --git a/renderer/vpt.py b/renderer/vpt.py index d113e70..f1f27fd 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -162,7 +162,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex = self.get_uv_item(self.textures, self.texture_img, obj_id, prim_id, u_coord, v_coord) + tex = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) diff --git a/scenes/cbox/cbox-vn.xml b/scenes/cbox/cbox-vn.xml new file mode 100755 index 0000000..bacfde4 --- /dev/null +++ b/scenes/cbox/cbox-vn.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scenes/meshes/cornell/flat-ball.obj b/scenes/meshes/cornell/flat-ball.obj new file mode 100644 index 0000000..9355b72 --- /dev/null +++ b/scenes/meshes/cornell/flat-ball.obj @@ -0,0 +1,2535 @@ +# Blender 3.5.1 +# www.blender.org +o Sphere.001 +v 4.018694 4.097396 2.700003 +v 4.018694 3.775584 2.378191 +v 4.018694 3.355116 2.204028 +v 4.018694 3.127560 2.181615 +v 4.018694 2.900005 2.204028 +v 4.018694 2.479537 2.378191 +v 4.063088 4.271559 3.124843 +v 4.105776 4.205184 2.910237 +v 4.145117 4.097396 2.712455 +v 4.179600 3.952338 2.539097 +v 4.207900 3.775584 2.396826 +v 4.228928 3.573927 2.291109 +v 4.241877 3.355116 2.226009 +v 4.246249 3.127560 2.204028 +v 4.241877 2.900005 2.226009 +v 4.228928 2.681194 2.291109 +v 4.207900 2.479537 2.396826 +v 4.179600 2.302783 2.539097 +v 4.145117 2.157725 2.712455 +v 4.105776 2.049937 2.910237 +v 4.063088 1.983562 3.124843 +v 4.105776 4.271559 3.137792 +v 4.189511 4.205184 2.935638 +v 4.266682 4.097396 2.749331 +v 4.334322 3.952338 2.586031 +v 4.389834 3.775584 2.452015 +v 4.431082 3.573927 2.352432 +v 4.456483 3.355116 2.291109 +v 4.465060 3.127560 2.270403 +v 4.456483 2.900005 2.291109 +v 4.431082 2.681194 2.352432 +v 4.389834 2.479537 2.452015 +v 4.334322 2.302783 2.586031 +v 4.266682 2.157725 2.749331 +v 4.189511 2.049937 2.935638 +v 4.105776 1.983562 3.137792 +v 4.145117 4.271559 3.158821 +v 4.266682 4.205184 2.976886 +v 4.378716 4.097396 2.809215 +v 4.476915 3.952338 2.662249 +v 4.557506 3.775584 2.541638 +v 4.617389 3.573927 2.452015 +v 4.654265 3.355116 2.396826 +v 4.666717 3.127560 2.378191 +v 4.654265 2.900005 2.396826 +v 4.617389 2.681194 2.452015 +v 4.557506 2.479537 2.541638 +v 4.476915 2.302783 2.662249 +v 4.378716 2.157725 2.809215 +v 4.266682 2.049937 2.976886 +v 4.145117 1.983562 3.158821 +v 4.179600 4.271559 3.187120 +v 4.334322 4.205184 3.032398 +v 4.476915 4.097396 2.889805 +v 4.601900 3.952338 2.764821 +v 4.704471 3.775584 2.662249 +v 4.780688 3.573927 2.586031 +v 4.827623 3.355116 2.539097 +v 4.843471 3.127560 2.523249 +v 4.827623 2.900005 2.539097 +v 4.780688 2.681194 2.586031 +v 4.704471 2.479537 2.662249 +v 4.601900 2.302783 2.764821 +v 4.476915 2.157725 2.889805 +v 4.334322 2.049937 3.032398 +v 4.179600 1.983562 3.187120 +v 4.207900 4.271559 3.221603 +v 4.389834 4.205184 3.100039 +v 4.557506 4.097396 2.988004 +v 4.704471 3.952338 2.889805 +v 4.825082 3.775584 2.809215 +v 4.914705 3.573927 2.749331 +v 4.969894 3.355116 2.712455 +v 4.988529 3.127560 2.700003 +v 4.969894 2.900005 2.712455 +v 4.914705 2.681194 2.749331 +v 4.825082 2.479537 2.809215 +v 4.704471 2.302783 2.889805 +v 4.557506 2.157725 2.988004 +v 4.389834 2.049937 3.100039 +v 4.207900 1.983562 3.221603 +v 4.018694 4.293972 3.348026 +v 4.228928 4.271559 3.260945 +v 4.431082 4.205184 3.177209 +v 4.617389 4.097396 3.100039 +v 4.780689 3.952338 3.032398 +v 4.914705 3.775584 2.976887 +v 5.014288 3.573927 2.935638 +v 5.075611 3.355116 2.910237 +v 5.096317 3.127560 2.901660 +v 5.075611 2.900005 2.910237 +v 5.014288 2.681194 2.935638 +v 4.914705 2.479537 2.976887 +v 4.780689 2.302783 3.032398 +v 4.617389 2.157725 3.100039 +v 4.431082 2.049937 3.177209 +v 4.228928 1.983562 3.260945 +v 4.241877 4.271559 3.303632 +v 4.456483 4.205184 3.260945 +v 4.654265 4.097396 3.221603 +v 4.827623 3.952338 3.187120 +v 4.969894 3.775584 3.158821 +v 5.075611 3.573927 3.137792 +v 5.140711 3.355116 3.124843 +v 5.162693 3.127560 3.120471 +v 5.140711 2.900005 3.124843 +v 5.075611 2.681194 3.137792 +v 4.969894 2.479537 3.158821 +v 4.827623 2.302783 3.187120 +v 4.654265 2.157725 3.221603 +v 4.456483 2.049937 3.260945 +v 4.241877 1.983562 3.303632 +v 4.246249 4.271559 3.348026 +v 4.465060 4.205184 3.348026 +v 4.666717 4.097396 3.348026 +v 4.843471 3.952338 3.348026 +v 4.988529 3.775584 3.348026 +v 5.096317 3.573927 3.348026 +v 5.162693 3.355116 3.348026 +v 5.185104 3.127560 3.348027 +v 5.162693 2.900005 3.348026 +v 5.096317 2.681194 3.348026 +v 4.988529 2.479537 3.348026 +v 4.843471 2.302783 3.348026 +v 4.666717 2.157725 3.348026 +v 4.465060 2.049937 3.348026 +v 4.246249 1.983562 3.348026 +v 4.241877 4.271559 3.392420 +v 4.456483 4.205184 3.435108 +v 4.654265 4.097396 3.474449 +v 4.827623 3.952338 3.508932 +v 4.969894 3.775584 3.537232 +v 5.075611 3.573927 3.558260 +v 5.140711 3.355116 3.571209 +v 5.162692 3.127560 3.575582 +v 5.140711 2.900005 3.571209 +v 5.075611 2.681194 3.558260 +v 4.969894 2.479537 3.537232 +v 4.827623 2.302783 3.508932 +v 4.654265 2.157725 3.474449 +v 4.456483 2.049937 3.435108 +v 4.241877 1.983562 3.392420 +v 4.228928 4.271559 3.435108 +v 4.431082 4.205184 3.518843 +v 4.617389 4.097396 3.596014 +v 4.780688 3.952338 3.663655 +v 4.914705 3.775584 3.719166 +v 5.014288 3.573927 3.760415 +v 5.075611 3.355116 3.785816 +v 5.096317 3.127560 3.794393 +v 5.075611 2.900005 3.785816 +v 5.014288 2.681194 3.760415 +v 4.914705 2.479537 3.719166 +v 4.780688 2.302783 3.663655 +v 4.617389 2.157725 3.596014 +v 4.431082 2.049937 3.518843 +v 4.228928 1.983562 3.435108 +v 4.207899 4.271559 3.474449 +v 4.389834 4.205184 3.596014 +v 4.557506 4.097396 3.708049 +v 4.704471 3.952338 3.806248 +v 4.825082 3.775584 3.886838 +v 4.914705 3.573927 3.946722 +v 4.969894 3.355116 3.983598 +v 4.988529 3.127560 3.996049 +v 4.969894 2.900005 3.983598 +v 4.914705 2.681194 3.946722 +v 4.825082 2.479537 3.886838 +v 4.704471 2.302783 3.806248 +v 4.557506 2.157725 3.708049 +v 4.389834 2.049937 3.596014 +v 4.207899 1.983562 3.474449 +v 4.179600 4.271559 3.508932 +v 4.334322 4.205184 3.663655 +v 4.476915 4.097396 3.806248 +v 4.601899 3.952338 3.931232 +v 4.704471 3.775584 4.033803 +v 4.780688 3.573927 4.110021 +v 4.827623 3.355116 4.156956 +v 4.843471 3.127560 4.172803 +v 4.827623 2.900005 4.156956 +v 4.780688 2.681194 4.110021 +v 4.704471 2.479537 4.033803 +v 4.601899 2.302783 3.931232 +v 4.476915 2.157725 3.806248 +v 4.334322 2.049937 3.663655 +v 4.179600 1.983562 3.508932 +v 4.145117 4.271559 3.537232 +v 4.266682 4.205184 3.719166 +v 4.378716 4.097396 3.886838 +v 4.476915 3.952338 4.033803 +v 4.557505 3.775584 4.154415 +v 4.617389 3.573927 4.244037 +v 4.654265 3.355116 4.299226 +v 4.666717 3.127560 4.317862 +v 4.654265 2.900005 4.299226 +v 4.617389 2.681194 4.244037 +v 4.557505 2.479537 4.154415 +v 4.476915 2.302783 4.033803 +v 4.378716 2.157725 3.886838 +v 4.266682 2.049937 3.719166 +v 4.145117 1.983562 3.537232 +v 4.105775 4.271559 3.558260 +v 4.189511 4.205184 3.760415 +v 4.266682 4.097396 3.946722 +v 4.334322 3.952338 4.110021 +v 4.389833 3.775584 4.244037 +v 4.431082 3.573927 4.343620 +v 4.456483 3.355116 4.404943 +v 4.465060 3.127560 4.425649 +v 4.456483 2.900005 4.404943 +v 4.431082 2.681194 4.343620 +v 4.389833 2.479537 4.244037 +v 4.334322 2.302783 4.110021 +v 4.266682 2.157725 3.946722 +v 4.189511 2.049937 3.760415 +v 4.105775 1.983562 3.558260 +v 4.063088 4.271559 3.571209 +v 4.105775 4.205184 3.785815 +v 4.145117 4.097396 3.983598 +v 4.179600 3.952338 4.156956 +v 4.207899 3.775584 4.299226 +v 4.228928 3.573927 4.404943 +v 4.241877 3.355116 4.470043 +v 4.246249 3.127560 4.492024 +v 4.241877 2.900005 4.470043 +v 4.228928 2.681194 4.404943 +v 4.207899 2.479537 4.299226 +v 4.179600 2.302783 4.156956 +v 4.145117 2.157725 3.983598 +v 4.105775 2.049937 3.785815 +v 4.063088 1.983562 3.571209 +v 4.018694 4.271559 3.575582 +v 4.018694 4.205184 3.794392 +v 4.018694 4.097396 3.996049 +v 4.018694 3.952338 4.172803 +v 4.018694 3.775584 4.317861 +v 4.018694 3.573927 4.425649 +v 4.018694 3.355116 4.492024 +v 4.018693 3.127560 4.514437 +v 4.018694 2.900005 4.492024 +v 4.018694 2.681194 4.425649 +v 4.018694 2.479537 4.317861 +v 4.018694 2.302783 4.172803 +v 4.018694 2.157725 3.996049 +v 4.018694 2.049937 3.794392 +v 4.018694 1.983562 3.575582 +v 3.974300 4.271559 3.571209 +v 3.931612 4.205184 3.785815 +v 3.892271 4.097396 3.983598 +v 3.857788 3.952338 4.156955 +v 3.829488 3.775584 4.299226 +v 3.808460 3.573927 4.404943 +v 3.795511 3.355116 4.470043 +v 3.791138 3.127560 4.492024 +v 3.795511 2.900005 4.470043 +v 3.808460 2.681194 4.404943 +v 3.829488 2.479537 4.299226 +v 3.857788 2.302783 4.156955 +v 3.892271 2.157725 3.983598 +v 3.931612 2.049937 3.785815 +v 3.974300 1.983562 3.571209 +v 3.931612 4.271559 3.558260 +v 3.847877 4.205184 3.760415 +v 3.770706 4.097396 3.946721 +v 3.703065 3.952338 4.110021 +v 3.647554 3.775584 4.244037 +v 3.606306 3.573927 4.343620 +v 3.580904 3.355116 4.404943 +v 3.572328 3.127560 4.425649 +v 3.580904 2.900005 4.404943 +v 3.606306 2.681194 4.343620 +v 3.647554 2.479537 4.244037 +v 3.703065 2.302783 4.110021 +v 3.770706 2.157725 3.946721 +v 3.847877 2.049937 3.760415 +v 3.931612 1.983562 3.558260 +v 3.892271 4.271559 3.537232 +v 3.770706 4.205184 3.719166 +v 3.658672 4.097396 3.886837 +v 3.560472 3.952338 4.033803 +v 3.479882 3.775584 4.154415 +v 3.419999 3.573927 4.244037 +v 3.383122 3.355116 4.299226 +v 3.370671 3.127560 4.317861 +v 3.383122 2.900005 4.299226 +v 3.419999 2.681194 4.244037 +v 3.479882 2.479537 4.154415 +v 3.560472 2.302783 4.033803 +v 3.658672 2.157725 3.886837 +v 3.770706 2.049937 3.719166 +v 3.892271 1.983562 3.537232 +v 3.857788 4.271559 3.508932 +v 3.703065 4.205184 3.663655 +v 3.560472 4.097396 3.806247 +v 3.435488 3.952338 3.931232 +v 3.332917 3.775584 4.033803 +v 3.256700 3.573927 4.110021 +v 3.209765 3.355116 4.156955 +v 3.193917 3.127560 4.172802 +v 3.209765 2.900005 4.156955 +v 3.256700 2.681194 4.110021 +v 3.332917 2.479537 4.033803 +v 3.435488 2.302783 3.931232 +v 3.560472 2.157725 3.806247 +v 3.703065 2.049937 3.663655 +v 3.857788 1.983562 3.508932 +v 4.018694 1.961149 3.348026 +v 3.829489 4.271559 3.474449 +v 3.647554 4.205184 3.596014 +v 3.479883 4.097396 3.708048 +v 3.332917 3.952338 3.806248 +v 3.212306 3.775584 3.886837 +v 3.122683 3.573927 3.946722 +v 3.067494 3.355116 3.983598 +v 3.048859 3.127560 3.996048 +v 3.067494 2.900005 3.983598 +v 3.122683 2.681194 3.946722 +v 3.212306 2.479537 3.886837 +v 3.332917 2.302783 3.806248 +v 3.479883 2.157725 3.708048 +v 3.647554 2.049937 3.596014 +v 3.829489 1.983562 3.474449 +v 3.808460 4.271559 3.435108 +v 3.606306 4.205184 3.518843 +v 3.419999 4.097396 3.596014 +v 3.256699 3.952338 3.663655 +v 3.122683 3.775584 3.719166 +v 3.023100 3.573927 3.760415 +v 2.961777 3.355116 3.785815 +v 2.941072 3.127560 3.794392 +v 2.961777 2.900005 3.785815 +v 3.023100 2.681194 3.760415 +v 3.122683 2.479537 3.719166 +v 3.256699 2.302783 3.663655 +v 3.419999 2.157725 3.596014 +v 3.606306 2.049937 3.518843 +v 3.808460 1.983562 3.435108 +v 3.795511 4.271559 3.392420 +v 3.580905 4.205184 3.435108 +v 3.383123 4.097396 3.474449 +v 3.209765 3.952338 3.508932 +v 3.067494 3.775584 3.537231 +v 2.961777 3.573927 3.558260 +v 2.896677 3.355116 3.571209 +v 2.874696 3.127560 3.575581 +v 2.896677 2.900005 3.571209 +v 2.961777 2.681194 3.558260 +v 3.067494 2.479537 3.537231 +v 3.209765 2.302783 3.508932 +v 3.383123 2.157725 3.474449 +v 3.580905 2.049937 3.435108 +v 3.795511 1.983562 3.392420 +v 3.791139 4.271559 3.348026 +v 3.572328 4.205184 3.348026 +v 3.370671 4.097396 3.348026 +v 3.193917 3.952338 3.348026 +v 3.048859 3.775584 3.348026 +v 2.941071 3.573927 3.348026 +v 2.874696 3.355116 3.348026 +v 2.852284 3.127560 3.348026 +v 2.874696 2.900005 3.348026 +v 2.941071 2.681194 3.348026 +v 3.048859 2.479537 3.348026 +v 3.193917 2.302783 3.348026 +v 3.370671 2.157725 3.348026 +v 3.572328 2.049937 3.348026 +v 3.791139 1.983562 3.348026 +v 3.795511 4.271559 3.303632 +v 3.580905 4.205184 3.260945 +v 3.383123 4.097396 3.221603 +v 3.209765 3.952338 3.187120 +v 3.067494 3.775584 3.158821 +v 2.961777 3.573927 3.137793 +v 2.896677 3.355116 3.124843 +v 2.874696 3.127560 3.120471 +v 2.896677 2.900005 3.124843 +v 2.961777 2.681194 3.137793 +v 3.067494 2.479537 3.158821 +v 3.209765 2.302783 3.187120 +v 3.383123 2.157725 3.221603 +v 3.580905 2.049937 3.260945 +v 3.795511 1.983562 3.303632 +v 3.808460 4.271559 3.260945 +v 3.606306 4.205184 3.177209 +v 3.419999 4.097396 3.100039 +v 3.256700 3.952338 3.032398 +v 3.122684 3.775584 2.976886 +v 3.023100 3.573927 2.935638 +v 2.961778 3.355116 2.910237 +v 2.941072 3.127560 2.901660 +v 2.961778 2.900005 2.910237 +v 3.023100 2.681194 2.935638 +v 3.122684 2.479537 2.976886 +v 3.256700 2.302783 3.032398 +v 3.419999 2.157725 3.100039 +v 3.606306 2.049937 3.177209 +v 3.808460 1.983562 3.260945 +v 3.829489 4.271559 3.221603 +v 3.647554 4.205184 3.100039 +v 3.479883 4.097396 2.988004 +v 3.332917 3.952338 2.889805 +v 3.212306 3.775584 2.809215 +v 3.122683 3.573927 2.749331 +v 3.067494 3.355116 2.712455 +v 3.048860 3.127560 2.700003 +v 3.067494 2.900005 2.712455 +v 3.122683 2.681194 2.749331 +v 3.212306 2.479537 2.809215 +v 3.332917 2.302783 2.889805 +v 3.479883 2.157725 2.988004 +v 3.647554 2.049937 3.100039 +v 3.829489 1.983562 3.221603 +v 3.857788 4.271559 3.187120 +v 3.703066 4.205184 3.032398 +v 3.560473 4.097396 2.889805 +v 3.435489 3.952338 2.764821 +v 3.332917 3.775584 2.662250 +v 3.256700 3.573927 2.586032 +v 3.209765 3.355116 2.539097 +v 3.193918 3.127560 2.523250 +v 3.209765 2.900005 2.539097 +v 3.256700 2.681194 2.586032 +v 3.332917 2.479537 2.662250 +v 3.435489 2.302783 2.764821 +v 3.560473 2.157725 2.889805 +v 3.703066 2.049937 3.032398 +v 3.857788 1.983562 3.187120 +v 3.892271 4.271559 3.158821 +v 3.770706 4.205184 2.976887 +v 3.658672 4.097396 2.809215 +v 3.560472 3.952338 2.662249 +v 3.479883 3.775584 2.541638 +v 3.419999 3.573927 2.452016 +v 3.383123 3.355116 2.396827 +v 3.370672 3.127560 2.378192 +v 3.383123 2.900005 2.396827 +v 3.419999 2.681194 2.452016 +v 3.479883 2.479537 2.541638 +v 3.560472 2.302783 2.662249 +v 3.658672 2.157725 2.809215 +v 3.770706 2.049937 2.976887 +v 3.892271 1.983562 3.158821 +v 3.931612 4.271559 3.137793 +v 3.847877 4.205184 2.935638 +v 3.770707 4.097396 2.749331 +v 3.703066 3.952338 2.586032 +v 3.647554 3.775584 2.452016 +v 3.606306 3.573927 2.352433 +v 3.580905 3.355116 2.291110 +v 3.572329 3.127560 2.270404 +v 3.580905 2.900005 2.291110 +v 3.606306 2.681194 2.352433 +v 3.647554 2.479537 2.452016 +v 3.703066 2.302783 2.586032 +v 3.770707 2.157725 2.749331 +v 3.847877 2.049937 2.935638 +v 3.931612 1.983562 3.137793 +v 3.974300 4.271559 3.124843 +v 3.931612 4.205184 2.910237 +v 3.892271 4.097396 2.712455 +v 3.857788 3.952338 2.539097 +v 3.829489 3.775584 2.396827 +v 3.808460 3.573927 2.291110 +v 3.795511 3.355116 2.226010 +v 3.791139 3.127560 2.204029 +v 3.795511 2.900005 2.226010 +v 3.808460 2.681194 2.291110 +v 3.829489 2.479537 2.396827 +v 3.857788 2.302783 2.539097 +v 3.892271 2.157725 2.712455 +v 3.931612 2.049937 2.910237 +v 3.974300 1.983562 3.124843 +v 4.018694 4.271559 3.120471 +v 4.018694 4.205184 2.901660 +v 4.018694 3.952338 2.523249 +v 4.018694 3.573927 2.270404 +v 4.018694 2.681194 2.270404 +v 4.018694 2.302783 2.523249 +v 4.018694 2.157725 2.700004 +v 4.018694 2.049937 2.901660 +v 4.018694 1.983562 3.120471 +vn 0.0624 -0.7715 -0.6332 +vn 0.0865 0.4696 -0.8786 +vn 0.0464 -0.8810 -0.4709 +vn 0.0938 0.2890 -0.9527 +vn 0.0286 -0.9565 -0.2902 +vn 0.0975 0.0975 -0.9904 +vn 0.0097 0.9951 -0.0980 +vn 0.0097 -0.9951 -0.0980 +vn 0.0975 -0.0976 -0.9904 +vn 0.0286 0.9565 -0.2902 +vn 0.0938 -0.2890 -0.9527 +vn 0.0464 0.8810 -0.4709 +vn 0.0865 -0.4696 -0.8786 +vn 0.0624 0.7715 -0.6332 +vn 0.0759 -0.6326 -0.7708 +vn 0.0759 0.6326 -0.7708 +vn 0.2248 -0.6326 -0.7412 +vn 0.2248 0.6326 -0.7412 +vn 0.1847 -0.7715 -0.6088 +vn 0.2563 0.4696 -0.8448 +vn 0.1374 -0.8810 -0.4528 +vn 0.2779 0.2890 -0.9161 +vn 0.0846 -0.9565 -0.2790 +vn 0.2889 0.0976 -0.9524 +vn 0.0286 0.9951 -0.0942 +vn 0.0286 -0.9951 -0.0942 +vn 0.2889 -0.0976 -0.9524 +vn 0.0846 0.9565 -0.2790 +vn 0.2779 -0.2890 -0.9161 +vn 0.1374 0.8810 -0.4528 +vn 0.2563 -0.4696 -0.8448 +vn 0.1847 0.7715 -0.6088 +vn 0.0464 0.9951 -0.0869 +vn 0.0464 -0.9951 -0.0869 +vn 0.4691 -0.0975 -0.8777 +vn 0.1374 0.9565 -0.2571 +vn 0.4513 -0.2890 -0.8443 +vn 0.2231 0.8810 -0.4173 +vn 0.4162 -0.4696 -0.7786 +vn 0.2999 0.7715 -0.5611 +vn 0.3651 -0.6326 -0.6831 +vn 0.3651 0.6326 -0.6831 +vn 0.2999 -0.7715 -0.5611 +vn 0.4162 0.4696 -0.7786 +vn 0.2230 -0.8810 -0.4173 +vn 0.4513 0.2890 -0.8443 +vn 0.1374 -0.9565 -0.2571 +vn 0.4691 0.0975 -0.8777 +vn 0.4913 0.6326 -0.5987 +vn 0.4036 -0.7715 -0.4918 +vn 0.5601 0.4696 -0.6825 +vn 0.3002 -0.8810 -0.3658 +vn 0.6073 0.2890 -0.7400 +vn 0.1850 -0.9565 -0.2254 +vn 0.6314 0.0975 -0.7693 +vn 0.0625 0.9951 -0.0761 +vn 0.0625 -0.9951 -0.0761 +vn 0.6314 -0.0975 -0.7693 +vn 0.1850 0.9565 -0.2254 +vn 0.6073 -0.2890 -0.7400 +vn 0.3002 0.8810 -0.3658 +vn 0.5601 -0.4696 -0.6825 +vn 0.4036 0.7715 -0.4918 +vn 0.4913 -0.6326 -0.5987 +vn 0.7693 -0.0975 -0.6314 +vn 0.2254 0.9565 -0.1850 +vn 0.7400 -0.2890 -0.6073 +vn 0.3658 0.8810 -0.3002 +vn 0.6825 -0.4696 -0.5601 +vn 0.4918 0.7715 -0.4036 +vn 0.5987 -0.6326 -0.4913 +vn 0.5987 0.6326 -0.4913 +vn 0.4918 -0.7715 -0.4036 +vn 0.6825 0.4696 -0.5601 +vn 0.3658 -0.8810 -0.3002 +vn 0.7400 0.2890 -0.6073 +vn 0.2254 -0.9566 -0.1850 +vn 0.7693 0.0975 -0.6314 +vn 0.0761 0.9951 -0.0625 +vn 0.0761 -0.9951 -0.0625 +vn 0.5611 -0.7715 -0.2999 +vn 0.7786 0.4696 -0.4162 +vn 0.4173 -0.8810 -0.2230 +vn 0.8443 0.2890 -0.4513 +vn 0.2571 -0.9565 -0.1374 +vn 0.8777 0.0975 -0.4691 +vn 0.0869 0.9951 -0.0464 +vn 0.0869 -0.9951 -0.0464 +vn 0.8777 -0.0975 -0.4691 +vn 0.2571 0.9565 -0.1374 +vn 0.8443 -0.2890 -0.4513 +vn 0.4173 0.8810 -0.2230 +vn 0.7786 -0.4696 -0.4162 +vn 0.5611 0.7715 -0.2999 +vn 0.6831 -0.6326 -0.3651 +vn 0.6831 0.6326 -0.3651 +vn 0.9161 -0.2890 -0.2779 +vn 0.4528 0.8810 -0.1374 +vn 0.8448 -0.4696 -0.2563 +vn 0.6088 0.7715 -0.1847 +vn 0.7412 -0.6326 -0.2248 +vn 0.7412 0.6326 -0.2248 +vn 0.6088 -0.7715 -0.1847 +vn 0.8448 0.4696 -0.2563 +vn 0.4528 -0.8810 -0.1374 +vn 0.9161 0.2890 -0.2779 +vn 0.2790 -0.9565 -0.0846 +vn 0.9524 0.0975 -0.2889 +vn 0.0942 0.9951 -0.0286 +vn 0.0942 -0.9951 -0.0286 +vn 0.9524 -0.0975 -0.2889 +vn 0.2790 0.9565 -0.0846 +vn 0.4709 -0.8810 -0.0464 +vn 0.9527 0.2890 -0.0938 +vn 0.2902 -0.9565 -0.0286 +vn 0.9904 0.0975 -0.0975 +vn 0.0980 0.9951 -0.0097 +vn 0.0980 -0.9951 -0.0097 +vn 0.9904 -0.0975 -0.0975 +vn 0.2902 0.9565 -0.0286 +vn 0.9527 -0.2890 -0.0938 +vn 0.4709 0.8810 -0.0464 +vn 0.8786 -0.4696 -0.0865 +vn 0.6332 0.7715 -0.0624 +vn 0.7708 -0.6326 -0.0759 +vn 0.7708 0.6326 -0.0759 +vn 0.6332 -0.7715 -0.0624 +vn 0.8786 0.4696 -0.0865 +vn 0.4709 0.8810 0.0464 +vn 0.8786 -0.4696 0.0865 +vn 0.6332 0.7715 0.0624 +vn 0.7708 -0.6326 0.0759 +vn 0.7708 0.6326 0.0759 +vn 0.6332 -0.7715 0.0624 +vn 0.8786 0.4696 0.0865 +vn 0.4709 -0.8810 0.0464 +vn 0.9527 0.2890 0.0938 +vn 0.2902 -0.9565 0.0286 +vn 0.9904 0.0975 0.0976 +vn 0.0980 0.9951 0.0097 +vn 0.0980 -0.9951 0.0097 +vn 0.9904 -0.0975 0.0976 +vn 0.2902 0.9565 0.0286 +vn 0.9527 -0.2890 0.0938 +vn 0.9161 0.2890 0.2779 +vn 0.2790 -0.9565 0.0846 +vn 0.9524 0.0975 0.2889 +vn 0.0942 0.9951 0.0286 +vn 0.0942 -0.9951 0.0286 +vn 0.9524 -0.0975 0.2889 +vn 0.2790 0.9565 0.0846 +vn 0.9161 -0.2890 0.2779 +vn 0.4528 0.8810 0.1374 +vn 0.8448 -0.4696 0.2563 +vn 0.6088 0.7715 0.1847 +vn 0.7412 -0.6326 0.2248 +vn 0.7412 0.6326 0.2248 +vn 0.6088 -0.7715 0.1847 +vn 0.8448 0.4696 0.2563 +vn 0.4528 -0.8810 0.1374 +vn 0.7786 -0.4696 0.4162 +vn 0.5611 0.7715 0.2999 +vn 0.6831 -0.6326 0.3651 +vn 0.6831 0.6326 0.3651 +vn 0.5611 -0.7715 0.2999 +vn 0.7786 0.4696 0.4162 +vn 0.4173 -0.8810 0.2230 +vn 0.8443 0.2890 0.4513 +vn 0.2571 -0.9565 0.1374 +vn 0.8777 0.0975 0.4691 +vn 0.0869 0.9951 0.0464 +vn 0.0869 -0.9951 0.0464 +vn 0.8777 -0.0975 0.4691 +vn 0.2571 0.9565 0.1374 +vn 0.8443 -0.2890 0.4513 +vn 0.4173 0.8810 0.2231 +vn 0.2254 -0.9565 0.1850 +vn 0.7693 0.0975 0.6314 +vn 0.0761 0.9951 0.0625 +vn 0.0761 -0.9951 0.0625 +vn 0.7693 -0.0975 0.6314 +vn 0.2254 0.9565 0.1850 +vn 0.7400 -0.2890 0.6073 +vn 0.3658 0.8810 0.3002 +vn 0.6825 -0.4696 0.5601 +vn 0.4918 0.7715 0.4036 +vn 0.5987 -0.6326 0.4913 +vn 0.5987 0.6326 0.4913 +vn 0.4918 -0.7715 0.4036 +vn 0.6825 0.4696 0.5601 +vn 0.3658 -0.8810 0.3002 +vn 0.7400 0.2890 0.6073 +vn 0.4036 0.7715 0.4918 +vn 0.4913 -0.6326 0.5987 +vn 0.4913 0.6326 0.5987 +vn 0.4036 -0.7715 0.4918 +vn 0.5601 0.4696 0.6825 +vn 0.3002 -0.8810 0.3658 +vn 0.6073 0.2890 0.7400 +vn 0.1850 -0.9565 0.2254 +vn 0.6314 0.0975 0.7693 +vn 0.0625 0.9951 0.0761 +vn 0.0625 -0.9951 0.0761 +vn 0.6314 -0.0975 0.7693 +vn 0.1850 0.9565 0.2254 +vn 0.6073 -0.2890 0.7400 +vn 0.3002 0.8810 0.3658 +vn 0.5601 -0.4696 0.6825 +vn 0.4691 0.0975 0.8777 +vn 0.0464 0.9951 0.0869 +vn 0.0464 -0.9951 0.0869 +vn 0.4691 -0.0975 0.8777 +vn 0.1374 0.9565 0.2571 +vn 0.4513 -0.2890 0.8443 +vn 0.2230 0.8810 0.4173 +vn 0.4162 -0.4696 0.7786 +vn 0.2999 0.7715 0.5611 +vn 0.3651 -0.6326 0.6831 +vn 0.3651 0.6326 0.6831 +vn 0.2999 -0.7715 0.5611 +vn 0.4162 0.4696 0.7786 +vn 0.2230 -0.8810 0.4173 +vn 0.4513 0.2890 0.8443 +vn 0.1374 -0.9565 0.2571 +vn 0.2248 -0.6326 0.7412 +vn 0.2248 0.6326 0.7412 +vn 0.1847 -0.7715 0.6088 +vn 0.2563 0.4696 0.8448 +vn 0.1374 -0.8810 0.4528 +vn 0.2779 0.2890 0.9161 +vn 0.0846 -0.9565 0.2790 +vn 0.2889 0.0975 0.9524 +vn 0.0286 0.9951 0.0942 +vn 0.0286 -0.9951 0.0942 +vn 0.2889 -0.0975 0.9524 +vn 0.0846 0.9565 0.2790 +vn 0.2779 -0.2890 0.9161 +vn 0.1374 0.8810 0.4528 +vn 0.2563 -0.4696 0.8448 +vn 0.1847 0.7715 0.6088 +vn 0.0097 -0.9951 0.0980 +vn 0.0975 -0.0975 0.9904 +vn 0.0286 0.9565 0.2902 +vn 0.0938 -0.2890 0.9527 +vn 0.0464 0.8810 0.4709 +vn 0.0865 -0.4696 0.8786 +vn 0.0624 0.7715 0.6332 +vn 0.0759 -0.6326 0.7708 +vn 0.0759 0.6326 0.7708 +vn 0.0624 -0.7715 0.6332 +vn 0.0865 0.4696 0.8786 +vn 0.0464 -0.8810 0.4709 +vn 0.0938 0.2890 0.9527 +vn 0.0286 -0.9565 0.2902 +vn 0.0975 0.0975 0.9904 +vn 0.0097 0.9951 0.0980 +vn -0.0624 -0.7715 0.6332 +vn -0.0865 0.4696 0.8786 +vn -0.0464 -0.8810 0.4709 +vn -0.0938 0.2890 0.9527 +vn -0.0286 -0.9565 0.2902 +vn -0.0976 0.0975 0.9904 +vn -0.0097 0.9951 0.0980 +vn -0.0097 -0.9951 0.0980 +vn -0.0975 -0.0975 0.9904 +vn -0.0286 0.9565 0.2902 +vn -0.0938 -0.2890 0.9527 +vn -0.0464 0.8810 0.4709 +vn -0.0865 -0.4696 0.8786 +vn -0.0624 0.7715 0.6332 +vn -0.0759 -0.6326 0.7708 +vn -0.0759 0.6326 0.7708 +vn -0.0846 0.9565 0.2790 +vn -0.2779 -0.2890 0.9161 +vn -0.1374 0.8810 0.4528 +vn -0.2563 -0.4696 0.8448 +vn -0.1847 0.7715 0.6088 +vn -0.2248 -0.6326 0.7412 +vn -0.2248 0.6326 0.7412 +vn -0.1847 -0.7715 0.6088 +vn -0.2563 0.4696 0.8448 +vn -0.1374 -0.8810 0.4528 +vn -0.2779 0.2890 0.9161 +vn -0.0846 -0.9565 0.2790 +vn -0.2889 0.0975 0.9524 +vn -0.0286 0.9951 0.0942 +vn -0.0286 -0.9951 0.0942 +vn -0.2889 -0.0975 0.9524 +vn -0.4162 0.4696 0.7786 +vn -0.2230 -0.8810 0.4173 +vn -0.4513 0.2890 0.8443 +vn -0.1374 -0.9565 0.2571 +vn -0.4691 0.0975 0.8777 +vn -0.0464 0.9951 0.0869 +vn -0.0464 -0.9951 0.0869 +vn -0.4691 -0.0975 0.8777 +vn -0.1374 0.9565 0.2571 +vn -0.4513 -0.2890 0.8443 +vn -0.2230 0.8810 0.4173 +vn -0.4162 -0.4696 0.7786 +vn -0.2999 0.7715 0.5611 +vn -0.3651 -0.6326 0.6831 +vn -0.3651 0.6326 0.6831 +vn -0.2999 -0.7715 0.5611 +vn -0.6073 -0.2890 0.7400 +vn -0.3002 0.8810 0.3658 +vn -0.5601 -0.4696 0.6825 +vn -0.4036 0.7715 0.4918 +vn -0.4913 -0.6326 0.5987 +vn -0.4913 0.6326 0.5987 +vn -0.4036 -0.7715 0.4918 +vn -0.5601 0.4696 0.6825 +vn -0.3002 -0.8810 0.3658 +vn -0.6073 0.2890 0.7400 +vn -0.1850 -0.9565 0.2254 +vn -0.6314 0.0975 0.7693 +vn -0.0625 0.9951 0.0761 +vn -0.0625 -0.9951 0.0761 +vn -0.6314 -0.0975 0.7693 +vn -0.1850 0.9565 0.2254 +vn -0.3658 -0.8810 0.3002 +vn -0.7400 0.2890 0.6073 +vn -0.2254 -0.9566 0.1850 +vn -0.7693 0.0975 0.6314 +vn -0.0761 0.9951 0.0625 +vn -0.0761 -0.9951 0.0625 +vn -0.7693 -0.0975 0.6314 +vn -0.2254 0.9565 0.1850 +vn -0.7400 -0.2890 0.6073 +vn -0.3658 0.8810 0.3002 +vn -0.6825 -0.4696 0.5601 +vn -0.4918 0.7715 0.4036 +vn -0.5987 -0.6326 0.4913 +vn -0.5987 0.6326 0.4913 +vn -0.4918 -0.7715 0.4036 +vn -0.6825 0.4696 0.5601 +vn -0.4173 0.8810 0.2230 +vn -0.7786 -0.4696 0.4162 +vn -0.5611 0.7715 0.2999 +vn -0.6831 -0.6326 0.3651 +vn -0.6831 0.6326 0.3651 +vn -0.5611 -0.7715 0.2999 +vn -0.7786 0.4696 0.4162 +vn -0.4173 -0.8810 0.2231 +vn -0.8443 0.2890 0.4513 +vn -0.2571 -0.9565 0.1374 +vn -0.8777 0.0975 0.4691 +vn -0.0869 0.9951 0.0464 +vn -0.0869 -0.9951 0.0464 +vn -0.8777 -0.0975 0.4691 +vn -0.2571 0.9565 0.1374 +vn -0.8443 -0.2890 0.4513 +vn -0.9161 0.2890 0.2779 +vn -0.2790 -0.9565 0.0846 +vn -0.9524 0.0975 0.2889 +vn -0.0942 0.9951 0.0286 +vn -0.0942 -0.9951 0.0286 +vn -0.9524 -0.0975 0.2889 +vn -0.2790 0.9565 0.0846 +vn -0.9161 -0.2890 0.2779 +vn -0.4528 0.8810 0.1374 +vn -0.8448 -0.4696 0.2563 +vn -0.6088 0.7715 0.1847 +vn -0.7412 -0.6326 0.2248 +vn -0.7412 0.6326 0.2248 +vn -0.6088 -0.7715 0.1847 +vn -0.8448 0.4696 0.2563 +vn -0.4528 -0.8810 0.1374 +vn -0.8786 -0.4696 0.0865 +vn -0.6332 0.7715 0.0624 +vn -0.7708 -0.6326 0.0759 +vn -0.7708 0.6326 0.0759 +vn -0.6332 -0.7715 0.0624 +vn -0.8786 0.4696 0.0865 +vn -0.4709 -0.8810 0.0464 +vn -0.9527 0.2890 0.0938 +vn -0.2902 -0.9565 0.0286 +vn -0.9904 0.0975 0.0975 +vn -0.0980 0.9951 0.0097 +vn -0.0980 -0.9951 0.0097 +vn -0.9904 -0.0975 0.0976 +vn -0.2902 0.9565 0.0286 +vn -0.9527 -0.2890 0.0938 +vn -0.4709 0.8810 0.0464 +vn -0.2902 -0.9565 -0.0286 +vn -0.9904 0.0975 -0.0975 +vn -0.0980 0.9951 -0.0097 +vn -0.0980 -0.9951 -0.0097 +vn -0.9904 -0.0975 -0.0976 +vn -0.2902 0.9565 -0.0286 +vn -0.9527 -0.2890 -0.0938 +vn -0.4709 0.8810 -0.0464 +vn -0.8786 -0.4696 -0.0865 +vn -0.6332 0.7715 -0.0624 +vn -0.7708 -0.6326 -0.0759 +vn -0.7708 0.6326 -0.0759 +vn -0.6332 -0.7715 -0.0624 +vn -0.8786 0.4696 -0.0865 +vn -0.4709 -0.8810 -0.0464 +vn -0.9527 0.2890 -0.0938 +vn -0.7412 -0.6326 -0.2248 +vn -0.7412 0.6326 -0.2248 +vn -0.6088 -0.7715 -0.1847 +vn -0.8448 0.4696 -0.2563 +vn -0.4528 -0.8810 -0.1374 +vn -0.9161 0.2890 -0.2779 +vn -0.2790 -0.9565 -0.0846 +vn -0.9524 0.0975 -0.2889 +vn -0.0942 0.9951 -0.0286 +vn -0.0942 -0.9951 -0.0286 +vn -0.9524 -0.0975 -0.2889 +vn -0.2790 0.9565 -0.0846 +vn -0.9161 -0.2890 -0.2779 +vn -0.4528 0.8810 -0.1374 +vn -0.8448 -0.4696 -0.2563 +vn -0.6088 0.7715 -0.1847 +vn -0.0869 0.9951 -0.0464 +vn -0.0869 -0.9951 -0.0464 +vn -0.8777 -0.0975 -0.4691 +vn -0.2571 0.9565 -0.1374 +vn -0.8443 -0.2890 -0.4513 +vn -0.4173 0.8810 -0.2231 +vn -0.7786 -0.4696 -0.4162 +vn -0.5611 0.7715 -0.2999 +vn -0.6831 -0.6326 -0.3651 +vn -0.6831 0.6326 -0.3651 +vn -0.5611 -0.7715 -0.2999 +vn -0.7786 0.4696 -0.4162 +vn -0.4173 -0.8810 -0.2231 +vn -0.8443 0.2890 -0.4513 +vn -0.2571 -0.9565 -0.1374 +vn -0.8777 0.0975 -0.4691 +vn -0.5987 0.6326 -0.4913 +vn -0.4918 -0.7715 -0.4036 +vn -0.6825 0.4696 -0.5601 +vn -0.3658 -0.8810 -0.3002 +vn -0.7400 0.2890 -0.6073 +vn -0.2254 -0.9565 -0.1850 +vn -0.7693 0.0975 -0.6314 +vn -0.0761 0.9951 -0.0625 +vn -0.0761 -0.9951 -0.0625 +vn -0.7693 -0.0975 -0.6314 +vn -0.2254 0.9565 -0.1850 +vn -0.7400 -0.2890 -0.6073 +vn -0.3658 0.8810 -0.3002 +vn -0.6825 -0.4696 -0.5601 +vn -0.4918 0.7715 -0.4036 +vn -0.5987 -0.6326 -0.4913 +vn -0.6314 -0.0975 -0.7693 +vn -0.1850 0.9565 -0.2254 +vn -0.6073 -0.2890 -0.7400 +vn -0.3002 0.8810 -0.3658 +vn -0.5601 -0.4696 -0.6825 +vn -0.4036 0.7715 -0.4918 +vn -0.4913 -0.6326 -0.5987 +vn -0.4913 0.6326 -0.5987 +vn -0.4036 -0.7715 -0.4918 +vn -0.5601 0.4696 -0.6825 +vn -0.3002 -0.8810 -0.3658 +vn -0.6073 0.2890 -0.7400 +vn -0.1850 -0.9565 -0.2254 +vn -0.6314 0.0975 -0.7693 +vn -0.0625 0.9951 -0.0761 +vn -0.0625 -0.9951 -0.0761 +vn -0.2999 -0.7715 -0.5611 +vn -0.4162 0.4696 -0.7786 +vn -0.2230 -0.8810 -0.4173 +vn -0.4513 0.2890 -0.8443 +vn -0.1374 -0.9565 -0.2571 +vn -0.4691 0.0975 -0.8777 +vn -0.0464 0.9951 -0.0869 +vn -0.0464 -0.9951 -0.0869 +vn -0.4691 -0.0975 -0.8777 +vn -0.1374 0.9565 -0.2571 +vn -0.4513 -0.2890 -0.8443 +vn -0.2230 0.8810 -0.4173 +vn -0.4162 -0.4696 -0.7786 +vn -0.2999 0.7715 -0.5611 +vn -0.3651 -0.6326 -0.6831 +vn -0.3651 0.6326 -0.6831 +vn -0.0846 0.9565 -0.2790 +vn -0.2779 -0.2890 -0.9161 +vn -0.1374 0.8810 -0.4528 +vn -0.2563 -0.4696 -0.8448 +vn -0.1847 0.7715 -0.6088 +vn -0.2248 -0.6326 -0.7412 +vn -0.2248 0.6326 -0.7412 +vn -0.1847 -0.7715 -0.6088 +vn -0.2563 0.4696 -0.8448 +vn -0.1374 -0.8810 -0.4528 +vn -0.2779 0.2890 -0.9161 +vn -0.0846 -0.9565 -0.2790 +vn -0.2889 0.0975 -0.9524 +vn -0.0286 0.9951 -0.0942 +vn -0.0286 -0.9951 -0.0942 +vn -0.2889 -0.0975 -0.9524 +vn -0.0865 0.4696 -0.8786 +vn -0.0464 -0.8810 -0.4709 +vn -0.0938 0.2890 -0.9527 +vn -0.0286 -0.9565 -0.2902 +vn -0.0976 0.0975 -0.9904 +vn -0.0097 0.9951 -0.0980 +vn -0.0097 -0.9951 -0.0980 +vn -0.0976 -0.0975 -0.9904 +vn -0.0286 0.9565 -0.2902 +vn -0.0938 -0.2890 -0.9527 +vn -0.0464 0.8810 -0.4709 +vn -0.0865 -0.4696 -0.8786 +vn -0.0624 0.7715 -0.6332 +vn -0.0759 -0.6326 -0.7708 +vn -0.0759 0.6326 -0.7708 +vn -0.0624 -0.7715 -0.6332 +vn 0.0975 0.0976 -0.9904 +vn 0.0975 -0.0975 -0.9904 +vn 0.2230 0.8810 -0.4173 +vn 0.2231 -0.8810 -0.4173 +vn 0.2254 -0.9565 -0.1850 +vn 0.4173 -0.8810 0.2231 +vn 0.2571 0.9566 0.1374 +vn 0.4173 0.8810 0.2230 +vn 0.2231 -0.8810 0.4173 +vn -0.0975 0.0975 0.9904 +vn -0.0976 -0.0975 0.9904 +vn -0.2231 -0.8810 0.4173 +vn -0.2231 0.8810 0.4173 +vn -0.2254 -0.9565 0.1850 +vn -0.4173 -0.8810 0.2230 +vn -0.9904 0.0975 0.0976 +vn -0.9904 -0.0975 0.0975 +vn -0.9904 0.0975 -0.0976 +vn -0.9904 -0.0975 -0.0975 +vt 0.750000 0.812500 +vt 0.750000 0.687500 +vt 0.750000 0.562500 +vt 0.750000 0.500000 +vt 0.750000 0.437500 +vt 0.750000 0.312500 +vt 0.718750 0.937500 +vt 0.718750 0.875000 +vt 0.718750 0.812500 +vt 0.718750 0.750000 +vt 0.718750 0.687500 +vt 0.718750 0.625000 +vt 0.718750 0.562500 +vt 0.718750 0.500000 +vt 0.718750 0.437500 +vt 0.718750 0.375000 +vt 0.718750 0.312500 +vt 0.718750 0.250000 +vt 0.718750 0.187500 +vt 0.718750 0.125000 +vt 0.718750 0.062500 +vt 0.687500 0.937500 +vt 0.687500 0.875000 +vt 0.687500 0.812500 +vt 0.687500 0.750000 +vt 0.687500 0.687500 +vt 0.687500 0.625000 +vt 0.687500 0.562500 +vt 0.687500 0.500000 +vt 0.687500 0.437500 +vt 0.687500 0.375000 +vt 0.687500 0.312500 +vt 0.687500 0.250000 +vt 0.687500 0.187500 +vt 0.687500 0.125000 +vt 0.687500 0.062500 +vt 0.656250 0.937500 +vt 0.656250 0.875000 +vt 0.656250 0.812500 +vt 0.656250 0.750000 +vt 0.656250 0.687500 +vt 0.656250 0.625000 +vt 0.656250 0.562500 +vt 0.656250 0.500000 +vt 0.656250 0.437500 +vt 0.656250 0.375000 +vt 0.656250 0.312500 +vt 0.656250 0.250000 +vt 0.656250 0.187500 +vt 0.656250 0.125000 +vt 0.656250 0.062500 +vt 0.625000 0.937500 +vt 0.625000 0.875000 +vt 0.625000 0.812500 +vt 0.625000 0.750000 +vt 0.625000 0.687500 +vt 0.625000 0.625000 +vt 0.625000 0.562500 +vt 0.625000 0.500000 +vt 0.625000 0.437500 +vt 0.625000 0.375000 +vt 0.625000 0.312500 +vt 0.625000 0.250000 +vt 0.625000 0.187500 +vt 0.625000 0.125000 +vt 0.625000 0.062500 +vt 0.593750 0.937500 +vt 0.593750 0.875000 +vt 0.593750 0.812500 +vt 0.593750 0.750000 +vt 0.593750 0.687500 +vt 0.593750 0.625000 +vt 0.593750 0.562500 +vt 0.593750 0.500000 +vt 0.593750 0.437500 +vt 0.593750 0.375000 +vt 0.593750 0.312500 +vt 0.593750 0.250000 +vt 0.593750 0.187500 +vt 0.593750 0.125000 +vt 0.593750 0.062500 +vt 0.734375 1.000000 +vt 0.703125 1.000000 +vt 0.671875 1.000000 +vt 0.640625 1.000000 +vt 0.609375 1.000000 +vt 0.578125 1.000000 +vt 0.546875 1.000000 +vt 0.515625 1.000000 +vt 0.484375 1.000000 +vt 0.453125 1.000000 +vt 0.421875 1.000000 +vt 0.390625 1.000000 +vt 0.359375 1.000000 +vt 0.328125 1.000000 +vt 0.296875 1.000000 +vt 0.265625 1.000000 +vt 0.234375 1.000000 +vt 0.203125 1.000000 +vt 0.171875 1.000000 +vt 0.140625 1.000000 +vt 0.109375 1.000000 +vt 0.078125 1.000000 +vt 0.046875 1.000000 +vt 0.015625 1.000000 +vt 0.984375 1.000000 +vt 0.953125 1.000000 +vt 0.921875 1.000000 +vt 0.890625 1.000000 +vt 0.859375 1.000000 +vt 0.828125 1.000000 +vt 0.796875 1.000000 +vt 0.765625 1.000000 +vt 0.562500 0.937500 +vt 0.562500 0.875000 +vt 0.562500 0.812500 +vt 0.562500 0.750000 +vt 0.562500 0.687500 +vt 0.562500 0.625000 +vt 0.562500 0.562500 +vt 0.562500 0.500000 +vt 0.562500 0.437500 +vt 0.562500 0.375000 +vt 0.562500 0.312500 +vt 0.562500 0.250000 +vt 0.562500 0.187500 +vt 0.562500 0.125000 +vt 0.562500 0.062500 +vt 0.531250 0.937500 +vt 0.531250 0.875000 +vt 0.531250 0.812500 +vt 0.531250 0.750000 +vt 0.531250 0.687500 +vt 0.531250 0.625000 +vt 0.531250 0.562500 +vt 0.531250 0.500000 +vt 0.531250 0.437500 +vt 0.531250 0.375000 +vt 0.531250 0.312500 +vt 0.531250 0.250000 +vt 0.531250 0.187500 +vt 0.531250 0.125000 +vt 0.531250 0.062500 +vt 0.500000 0.937500 +vt 0.500000 0.875000 +vt 0.500000 0.812500 +vt 0.500000 0.750000 +vt 0.500000 0.687500 +vt 0.500000 0.625000 +vt 0.500000 0.562500 +vt 0.500000 0.500000 +vt 0.500000 0.437500 +vt 0.500000 0.375000 +vt 0.500000 0.312500 +vt 0.500000 0.250000 +vt 0.500000 0.187500 +vt 0.500000 0.125000 +vt 0.500000 0.062500 +vt 0.468750 0.937500 +vt 0.468750 0.875000 +vt 0.468750 0.812500 +vt 0.468750 0.750000 +vt 0.468750 0.687500 +vt 0.468750 0.625000 +vt 0.468750 0.562500 +vt 0.468750 0.500000 +vt 0.468750 0.437500 +vt 0.468750 0.375000 +vt 0.468750 0.312500 +vt 0.468750 0.250000 +vt 0.468750 0.187500 +vt 0.468750 0.125000 +vt 0.468750 0.062500 +vt 0.437500 0.937500 +vt 0.437500 0.875000 +vt 0.437500 0.812500 +vt 0.437500 0.750000 +vt 0.437500 0.687500 +vt 0.437500 0.625000 +vt 0.437500 0.562500 +vt 0.437500 0.500000 +vt 0.437500 0.437500 +vt 0.437500 0.375000 +vt 0.437500 0.312500 +vt 0.437500 0.250000 +vt 0.437500 0.187500 +vt 0.437500 0.125000 +vt 0.437500 0.062500 +vt 0.406250 0.937500 +vt 0.406250 0.875000 +vt 0.406250 0.812500 +vt 0.406250 0.750000 +vt 0.406250 0.687500 +vt 0.406250 0.625000 +vt 0.406250 0.562500 +vt 0.406250 0.500000 +vt 0.406250 0.437500 +vt 0.406250 0.375000 +vt 0.406250 0.312500 +vt 0.406250 0.250000 +vt 0.406250 0.187500 +vt 0.406250 0.125000 +vt 0.406250 0.062500 +vt 0.375000 0.937500 +vt 0.375000 0.875000 +vt 0.375000 0.812500 +vt 0.375000 0.750000 +vt 0.375000 0.687500 +vt 0.375000 0.625000 +vt 0.375000 0.562500 +vt 0.375000 0.500000 +vt 0.375000 0.437500 +vt 0.375000 0.375000 +vt 0.375000 0.312500 +vt 0.375000 0.250000 +vt 0.375000 0.187500 +vt 0.375000 0.125000 +vt 0.375000 0.062500 +vt 0.343750 0.937500 +vt 0.343750 0.875000 +vt 0.343750 0.812500 +vt 0.343750 0.750000 +vt 0.343750 0.687500 +vt 0.343750 0.625000 +vt 0.343750 0.562500 +vt 0.343750 0.500000 +vt 0.343750 0.437500 +vt 0.343750 0.375000 +vt 0.343750 0.312500 +vt 0.343750 0.250000 +vt 0.343750 0.187500 +vt 0.343750 0.125000 +vt 0.343750 0.062500 +vt 0.312500 0.937500 +vt 0.312500 0.875000 +vt 0.312500 0.812500 +vt 0.312500 0.750000 +vt 0.312500 0.687500 +vt 0.312500 0.625000 +vt 0.312500 0.562500 +vt 0.312500 0.500000 +vt 0.312500 0.437500 +vt 0.312500 0.375000 +vt 0.312500 0.312500 +vt 0.312500 0.250000 +vt 0.312500 0.187500 +vt 0.312500 0.125000 +vt 0.312500 0.062500 +vt 0.281250 0.937500 +vt 0.281250 0.875000 +vt 0.281250 0.812500 +vt 0.281250 0.750000 +vt 0.281250 0.687500 +vt 0.281250 0.625000 +vt 0.281250 0.562500 +vt 0.281250 0.500000 +vt 0.281250 0.437500 +vt 0.281250 0.375000 +vt 0.281250 0.312500 +vt 0.281250 0.250000 +vt 0.281250 0.187500 +vt 0.281250 0.125000 +vt 0.281250 0.062500 +vt 0.250000 0.937500 +vt 0.250000 0.875000 +vt 0.250000 0.812500 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.250000 0.625000 +vt 0.250000 0.562500 +vt 0.250000 0.500000 +vt 0.250000 0.437500 +vt 0.250000 0.375000 +vt 0.250000 0.312500 +vt 0.250000 0.250000 +vt 0.250000 0.187500 +vt 0.250000 0.125000 +vt 0.250000 0.062500 +vt 0.218750 0.937500 +vt 0.218750 0.875000 +vt 0.218750 0.812500 +vt 0.218750 0.750000 +vt 0.218750 0.687500 +vt 0.218750 0.625000 +vt 0.218750 0.562500 +vt 0.218750 0.500000 +vt 0.218750 0.437500 +vt 0.218750 0.375000 +vt 0.218750 0.312500 +vt 0.218750 0.250000 +vt 0.218750 0.187500 +vt 0.218750 0.125000 +vt 0.218750 0.062500 +vt 0.187500 0.937500 +vt 0.187500 0.875000 +vt 0.187500 0.812500 +vt 0.187500 0.750000 +vt 0.187500 0.687500 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.187500 0.187500 +vt 0.187500 0.125000 +vt 0.187500 0.062500 +vt 0.156250 0.937500 +vt 0.156250 0.875000 +vt 0.156250 0.812500 +vt 0.156250 0.750000 +vt 0.156250 0.687500 +vt 0.156250 0.625000 +vt 0.156250 0.562500 +vt 0.156250 0.500000 +vt 0.156250 0.437500 +vt 0.156250 0.375000 +vt 0.156250 0.312500 +vt 0.156250 0.250000 +vt 0.156250 0.187500 +vt 0.156250 0.125000 +vt 0.156250 0.062500 +vt 0.125000 0.937500 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.125000 0.750000 +vt 0.125000 0.687500 +vt 0.125000 0.625000 +vt 0.125000 0.562500 +vt 0.125000 0.500000 +vt 0.125000 0.437500 +vt 0.125000 0.375000 +vt 0.125000 0.312500 +vt 0.125000 0.250000 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.125000 0.062500 +vt 0.734375 0.000000 +vt 0.703125 0.000000 +vt 0.671875 0.000000 +vt 0.640625 0.000000 +vt 0.609375 0.000000 +vt 0.578125 0.000000 +vt 0.546875 0.000000 +vt 0.515625 0.000000 +vt 0.484375 0.000000 +vt 0.453125 0.000000 +vt 0.421875 0.000000 +vt 0.390625 0.000000 +vt 0.359375 0.000000 +vt 0.328125 0.000000 +vt 0.296875 0.000000 +vt 0.265625 0.000000 +vt 0.234375 0.000000 +vt 0.203125 0.000000 +vt 0.171875 0.000000 +vt 0.140625 0.000000 +vt 0.109375 0.000000 +vt 0.078125 0.000000 +vt 0.046875 0.000000 +vt 0.015625 0.000000 +vt 0.984375 0.000000 +vt 0.953125 0.000000 +vt 0.921875 0.000000 +vt 0.890625 0.000000 +vt 0.859375 0.000000 +vt 0.828125 0.000000 +vt 0.796875 0.000000 +vt 0.765625 0.000000 +vt 0.093750 0.937500 +vt 0.093750 0.875000 +vt 0.093750 0.812500 +vt 0.093750 0.750000 +vt 0.093750 0.687500 +vt 0.093750 0.625000 +vt 0.093750 0.562500 +vt 0.093750 0.500000 +vt 0.093750 0.437500 +vt 0.093750 0.375000 +vt 0.093750 0.312500 +vt 0.093750 0.250000 +vt 0.093750 0.187500 +vt 0.093750 0.125000 +vt 0.093750 0.062500 +vt 0.062500 0.937500 +vt 0.062500 0.875000 +vt 0.062500 0.812500 +vt 0.062500 0.750000 +vt 0.062500 0.687500 +vt 0.062500 0.625000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.062500 0.437500 +vt 0.062500 0.375000 +vt 0.062500 0.312500 +vt 0.062500 0.250000 +vt 0.062500 0.187500 +vt 0.062500 0.125000 +vt 0.062500 0.062500 +vt 0.031250 0.937500 +vt 0.031250 0.875000 +vt 0.031250 0.812500 +vt 0.031250 0.750000 +vt 0.031250 0.687500 +vt 0.031250 0.625000 +vt 0.031250 0.562500 +vt 0.031250 0.500000 +vt 0.031250 0.437500 +vt 0.031250 0.375000 +vt 0.031250 0.312500 +vt 0.031250 0.250000 +vt 0.031250 0.187500 +vt 0.031250 0.125000 +vt 0.031250 0.062500 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 0.000000 0.875000 +vt 1.000000 0.875000 +vt 0.000000 0.812500 +vt 1.000000 0.812500 +vt 0.000000 0.750000 +vt 1.000000 0.750000 +vt 0.000000 0.687500 +vt 1.000000 0.687500 +vt 0.000000 0.625000 +vt 1.000000 0.625000 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 0.000000 0.437500 +vt 1.000000 0.437500 +vt 0.000000 0.375000 +vt 1.000000 0.375000 +vt 0.000000 0.312500 +vt 1.000000 0.312500 +vt 0.000000 0.250000 +vt 1.000000 0.250000 +vt 0.000000 0.187500 +vt 1.000000 0.187500 +vt 0.000000 0.125000 +vt 1.000000 0.125000 +vt 1.000000 0.062500 +vt 0.000000 0.062500 +vt 0.968750 0.937500 +vt 0.968750 0.875000 +vt 0.968750 0.812500 +vt 0.968750 0.750000 +vt 0.968750 0.687500 +vt 0.968750 0.625000 +vt 0.968750 0.562500 +vt 0.968750 0.500000 +vt 0.968750 0.437500 +vt 0.968750 0.375000 +vt 0.968750 0.312500 +vt 0.968750 0.250000 +vt 0.968750 0.187500 +vt 0.968750 0.125000 +vt 0.968750 0.062500 +vt 0.937500 0.937500 +vt 0.937500 0.875000 +vt 0.937500 0.812500 +vt 0.937500 0.750000 +vt 0.937500 0.687500 +vt 0.937500 0.625000 +vt 0.937500 0.562500 +vt 0.937500 0.500000 +vt 0.937500 0.437500 +vt 0.937500 0.375000 +vt 0.937500 0.312500 +vt 0.937500 0.250000 +vt 0.937500 0.187500 +vt 0.937500 0.125000 +vt 0.937500 0.062500 +vt 0.906250 0.937500 +vt 0.906250 0.875000 +vt 0.906250 0.812500 +vt 0.906250 0.750000 +vt 0.906250 0.687500 +vt 0.906250 0.625000 +vt 0.906250 0.562500 +vt 0.906250 0.500000 +vt 0.906250 0.437500 +vt 0.906250 0.375000 +vt 0.906250 0.312500 +vt 0.906250 0.250000 +vt 0.906250 0.187500 +vt 0.906250 0.125000 +vt 0.906250 0.062500 +vt 0.875000 0.937500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.875000 0.750000 +vt 0.875000 0.687500 +vt 0.875000 0.625000 +vt 0.875000 0.562500 +vt 0.875000 0.500000 +vt 0.875000 0.437500 +vt 0.875000 0.375000 +vt 0.875000 0.312500 +vt 0.875000 0.250000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.875000 0.062500 +vt 0.843750 0.937500 +vt 0.843750 0.875000 +vt 0.843750 0.812500 +vt 0.843750 0.750000 +vt 0.843750 0.687500 +vt 0.843750 0.625000 +vt 0.843750 0.562500 +vt 0.843750 0.500000 +vt 0.843750 0.437500 +vt 0.843750 0.375000 +vt 0.843750 0.312500 +vt 0.843750 0.250000 +vt 0.843750 0.187500 +vt 0.843750 0.125000 +vt 0.843750 0.062500 +vt 0.812500 0.937500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.812500 0.750000 +vt 0.812500 0.687500 +vt 0.812500 0.625000 +vt 0.812500 0.562500 +vt 0.812500 0.500000 +vt 0.812500 0.437500 +vt 0.812500 0.375000 +vt 0.812500 0.312500 +vt 0.812500 0.250000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.812500 0.062500 +vt 0.781250 0.937500 +vt 0.781250 0.875000 +vt 0.781250 0.812500 +vt 0.781250 0.750000 +vt 0.781250 0.687500 +vt 0.781250 0.625000 +vt 0.781250 0.562500 +vt 0.781250 0.500000 +vt 0.781250 0.437500 +vt 0.781250 0.375000 +vt 0.781250 0.312500 +vt 0.781250 0.250000 +vt 0.781250 0.187500 +vt 0.781250 0.125000 +vt 0.781250 0.062500 +vt 0.750000 0.937500 +vt 0.750000 0.875000 +vt 0.750000 0.750000 +vt 0.750000 0.625000 +vt 0.750000 0.375000 +vt 0.750000 0.250000 +vt 0.750000 0.187500 +vt 0.750000 0.125000 +vt 0.750000 0.062500 +f 479/556/1 19/19/1 480/557/1 +f 477/554/2 11/11/2 12/12/2 +f 480/557/3 20/20/3 481/558/3 +f 3/3/4 12/12/4 13/13/4 +f 481/558/5 21/21/5 482/559/5 +f 3/3/6 14/14/6 4/4/6 +f 474/551/7 82/82/7 7/7/7 +f 308/339/8 482/559/8 21/21/8 +f 4/4/9 15/15/9 5/5/9 +f 475/552/10 7/7/10 8/8/10 +f 5/5/11 16/16/11 478/555/11 +f 1/1/12 8/8/12 9/9/12 +f 478/555/13 17/17/13 6/6/13 +f 476/553/14 9/9/14 10/10/14 +f 6/6/15 18/18/15 479/556/15 +f 2/2/16 10/10/16 11/11/16 +f 17/17/17 33/33/17 18/18/17 +f 10/10/18 26/26/18 11/11/18 +f 19/19/19 33/33/19 34/34/19 +f 11/11/20 27/27/20 12/12/20 +f 20/20/21 34/34/21 35/35/21 +f 13/13/22 27/27/22 28/28/22 +f 20/20/23 36/36/23 21/21/23 +f 13/13/24 29/29/24 14/14/24 +f 7/7/25 82/83/25 22/22/25 +f 308/340/26 21/21/26 36/36/26 +f 14/14/27 30/30/27 15/15/27 +f 7/7/28 23/23/28 8/8/28 +f 15/15/29 31/31/29 16/16/29 +f 8/8/30 24/24/30 9/9/30 +f 16/16/31 32/32/31 17/17/31 +f 9/9/32 25/25/32 10/10/32 +f 22/22/33 82/84/33 37/37/33 +f 308/341/34 36/36/34 51/51/34 +f 30/30/35 44/44/35 45/45/35 +f 22/22/36 38/38/36 23/23/36 +f 30/30/37 46/46/37 31/31/37 +f 23/23/38 39/39/38 24/24/38 +f 32/32/39 46/46/39 47/47/39 +f 24/24/40 40/40/40 25/25/40 +f 33/33/41 47/47/41 48/48/41 +f 25/25/42 41/41/42 26/26/42 +f 34/34/43 48/48/43 49/49/43 +f 26/26/44 42/42/44 27/27/44 +f 34/34/45 50/50/45 35/35/45 +f 27/27/46 43/43/46 28/28/46 +f 35/35/47 51/51/47 36/36/47 +f 28/28/48 44/44/48 29/29/48 +f 40/40/49 56/56/49 41/41/49 +f 48/48/50 64/64/50 49/49/50 +f 41/41/51 57/57/51 42/42/51 +f 49/49/52 65/65/52 50/50/52 +f 43/43/53 57/57/53 58/58/53 +f 50/50/54 66/66/54 51/51/54 +f 44/44/55 58/58/55 59/59/55 +f 37/37/56 82/85/56 52/52/56 +f 308/342/57 51/51/57 66/66/57 +f 44/44/58 60/60/58 45/45/58 +f 37/37/59 53/53/59 38/38/59 +f 45/45/60 61/61/60 46/46/60 +f 38/38/61 54/54/61 39/39/61 +f 47/47/62 61/61/62 62/62/62 +f 39/39/63 55/55/63 40/40/63 +f 47/47/64 63/63/64 48/48/64 +f 59/59/65 75/75/65 60/60/65 +f 52/52/66 68/68/66 53/53/66 +f 60/60/67 76/76/67 61/61/67 +f 53/53/68 69/69/68 54/54/68 +f 62/62/69 76/76/69 77/77/69 +f 54/54/70 70/70/70 55/55/70 +f 62/62/71 78/78/71 63/63/71 +f 56/56/72 70/70/72 71/71/72 +f 63/63/73 79/79/73 64/64/73 +f 56/56/74 72/72/74 57/57/74 +f 65/65/75 79/79/75 80/80/75 +f 58/58/76 72/72/76 73/73/76 +f 65/65/77 81/81/77 66/66/77 +f 59/59/78 73/73/78 74/74/78 +f 52/52/79 82/86/79 67/67/79 +f 308/343/80 66/66/80 81/81/80 +f 78/78/81 95/126/81 79/79/81 +f 71/71/82 88/119/82 72/72/82 +f 79/79/83 96/127/83 80/80/83 +f 73/73/84 88/119/84 89/120/84 +f 81/81/85 96/127/85 97/128/85 +f 74/74/86 89/120/86 90/121/86 +f 67/67/87 82/87/87 83/114/87 +f 308/344/88 81/81/88 97/128/88 +f 74/74/89 91/122/89 75/75/89 +f 67/67/90 84/115/90 68/68/90 +f 75/75/91 92/123/91 76/76/91 +f 68/68/92 85/116/92 69/69/92 +f 77/77/93 92/123/93 93/124/93 +f 69/69/94 86/117/94 70/70/94 +f 77/77/95 94/125/95 78/78/95 +f 71/71/96 86/117/96 87/118/96 +f 91/122/97 107/138/97 92/123/97 +f 84/115/98 100/131/98 85/116/98 +f 93/124/99 107/138/99 108/139/99 +f 85/116/100 101/132/100 86/117/100 +f 93/124/101 109/140/101 94/125/101 +f 87/118/102 101/132/102 102/133/102 +f 95/126/103 109/140/103 110/141/103 +f 87/118/104 103/134/104 88/119/104 +f 96/127/105 110/141/105 111/142/105 +f 89/120/106 103/134/106 104/135/106 +f 96/127/107 112/143/107 97/128/107 +f 90/121/108 104/135/108 105/136/108 +f 83/114/109 82/88/109 98/129/109 +f 308/345/110 97/128/110 112/143/110 +f 90/121/111 106/137/111 91/122/111 +f 84/115/112 98/129/112 99/130/112 +f 110/141/113 126/157/113 111/142/113 +f 104/135/114 118/149/114 119/150/114 +f 111/142/115 127/158/115 112/143/115 +f 105/136/116 119/150/116 120/151/116 +f 98/129/117 82/89/117 113/144/117 +f 308/346/118 112/143/118 127/158/118 +f 105/136/119 121/152/119 106/137/119 +f 99/130/120 113/144/120 114/145/120 +f 106/137/121 122/153/121 107/138/121 +f 99/130/122 115/146/122 100/131/122 +f 108/139/123 122/153/123 123/154/123 +f 100/131/124 116/147/124 101/132/124 +f 108/139/125 124/155/125 109/140/125 +f 102/133/126 116/147/126 117/148/126 +f 110/141/127 124/155/127 125/156/127 +f 102/133/128 118/149/128 103/134/128 +f 114/145/129 130/161/129 115/146/129 +f 123/154/130 137/168/130 138/169/130 +f 115/146/131 131/162/131 116/147/131 +f 123/154/132 139/170/132 124/155/132 +f 117/148/133 131/162/133 132/163/133 +f 125/156/134 139/170/134 140/171/134 +f 117/148/135 133/164/135 118/149/135 +f 125/156/136 141/172/136 126/157/136 +f 119/150/137 133/164/137 134/165/137 +f 126/157/138 142/173/138 127/158/138 +f 120/151/139 134/165/139 135/166/139 +f 113/144/140 82/90/140 128/159/140 +f 308/347/141 127/158/141 142/173/141 +f 120/151/142 136/167/142 121/152/142 +f 113/144/143 129/160/143 114/145/143 +f 121/152/144 137/168/144 122/153/144 +f 134/165/145 148/179/145 149/180/145 +f 142/173/146 156/187/146 157/188/146 +f 135/166/147 149/180/147 150/181/147 +f 128/159/148 82/91/148 143/174/148 +f 308/348/149 142/173/149 157/188/149 +f 135/166/150 151/182/150 136/167/150 +f 128/159/151 144/175/151 129/160/151 +f 136/167/152 152/183/152 137/168/152 +f 130/161/153 144/175/153 145/176/153 +f 138/169/154 152/183/154 153/184/154 +f 130/161/155 146/177/155 131/162/155 +f 138/169/156 154/185/156 139/170/156 +f 132/163/157 146/177/157 147/178/157 +f 140/171/158 154/185/158 155/186/158 +f 132/163/159 148/179/159 133/164/159 +f 140/171/160 156/187/160 141/172/160 +f 153/184/161 167/198/161 168/199/161 +f 145/176/162 161/192/162 146/177/162 +f 153/184/163 169/200/163 154/185/163 +f 147/178/164 161/192/164 162/193/164 +f 155/186/165 169/200/165 170/201/165 +f 147/178/166 163/194/166 148/179/166 +f 155/186/167 171/202/167 156/187/167 +f 149/180/168 163/194/168 164/195/168 +f 156/187/169 172/203/169 157/188/169 +f 150/181/170 164/195/170 165/196/170 +f 143/174/171 82/92/171 158/189/171 +f 308/349/172 157/188/172 172/203/172 +f 150/181/173 166/197/173 151/182/173 +f 143/174/174 159/190/174 144/175/174 +f 151/182/175 167/198/175 152/183/175 +f 145/176/176 159/190/176 160/191/176 +f 172/203/177 186/217/177 187/218/177 +f 165/196/178 179/210/178 180/211/178 +f 158/189/179 82/93/179 173/204/179 +f 308/350/180 172/203/180 187/218/180 +f 165/196/181 181/212/181 166/197/181 +f 158/189/182 174/205/182 159/190/182 +f 166/197/183 182/213/183 167/198/183 +f 159/190/184 175/206/184 160/191/184 +f 168/199/185 182/213/185 183/214/185 +f 160/191/186 176/207/186 161/192/186 +f 168/199/187 184/215/187 169/200/187 +f 162/193/188 176/207/188 177/208/188 +f 169/200/189 185/216/189 170/201/189 +f 162/193/190 178/209/190 163/194/190 +f 171/202/191 185/216/191 186/217/191 +f 164/195/192 178/209/192 179/210/192 +f 175/206/193 191/222/193 176/207/193 +f 183/214/194 199/230/194 184/215/194 +f 177/208/195 191/222/195 192/223/195 +f 185/216/196 199/230/196 200/231/196 +f 177/208/197 193/224/197 178/209/197 +f 185/216/198 201/232/198 186/217/198 +f 179/210/199 193/224/199 194/225/199 +f 186/217/200 202/233/200 187/218/200 +f 180/211/201 194/225/201 195/226/201 +f 173/204/202 82/94/202 188/219/202 +f 308/351/203 187/218/203 202/233/203 +f 180/211/204 196/227/204 181/212/204 +f 174/205/205 188/219/205 189/220/205 +f 181/212/206 197/228/206 182/213/206 +f 175/206/207 189/220/207 190/221/207 +f 183/214/208 197/228/208 198/229/208 +f 195/226/209 209/240/209 210/241/209 +f 188/219/210 82/95/210 203/234/210 +f 308/352/211 202/233/211 217/248/211 +f 195/226/212 211/242/212 196/227/212 +f 188/219/213 204/235/213 189/220/213 +f 196/227/214 212/243/214 197/228/214 +f 189/220/215 205/236/215 190/221/215 +f 198/229/216 212/243/216 213/244/216 +f 190/221/217 206/237/217 191/222/217 +f 198/229/218 214/245/218 199/230/218 +f 192/223/219 206/237/219 207/238/219 +f 200/231/220 214/245/220 215/246/220 +f 192/223/221 208/239/221 193/224/221 +f 200/231/222 216/247/222 201/232/222 +f 194/225/223 208/239/223 209/240/223 +f 201/232/224 217/248/224 202/233/224 +f 213/244/225 229/260/225 214/245/225 +f 207/238/226 221/252/226 222/253/226 +f 215/246/227 229/260/227 230/261/227 +f 207/238/228 223/254/228 208/239/228 +f 215/246/229 231/262/229 216/247/229 +f 209/240/230 223/254/230 224/255/230 +f 216/247/231 232/263/231 217/248/231 +f 210/241/232 224/255/232 225/256/232 +f 203/234/233 82/96/233 218/249/233 +f 308/353/234 217/248/234 232/263/234 +f 210/241/235 226/257/235 211/242/235 +f 203/234/236 219/250/236 204/235/236 +f 211/242/237 227/258/237 212/243/237 +f 204/235/238 220/251/238 205/236/238 +f 213/244/239 227/258/239 228/259/239 +f 205/236/240 221/252/240 206/237/240 +f 308/354/241 232/263/241 247/278/241 +f 225/256/242 241/272/242 226/257/242 +f 218/249/243 234/265/243 219/250/243 +f 226/257/244 242/273/244 227/258/244 +f 220/251/245 234/265/245 235/266/245 +f 228/259/246 242/273/246 243/274/246 +f 220/251/247 236/267/247 221/252/247 +f 228/259/248 244/275/248 229/260/248 +f 222/253/249 236/267/249 237/268/249 +f 230/261/250 244/275/250 245/276/250 +f 222/253/251 238/269/251 223/254/251 +f 230/261/252 246/277/252 231/262/252 +f 224/255/253 238/269/253 239/270/253 +f 232/263/254 246/277/254 247/278/254 +f 225/256/255 239/270/255 240/271/255 +f 218/249/256 82/97/256 233/264/256 +f 245/276/257 259/290/257 260/291/257 +f 237/268/258 253/284/258 238/269/258 +f 245/276/259 261/292/259 246/277/259 +f 239/270/260 253/284/260 254/285/260 +f 246/277/261 262/293/261 247/278/261 +f 240/271/262 254/285/262 255/286/262 +f 233/264/263 82/98/263 248/279/263 +f 308/355/264 247/278/264 262/293/264 +f 240/271/265 256/287/265 241/272/265 +f 233/264/266 249/280/266 234/265/266 +f 241/272/267 257/288/267 242/273/267 +f 234/265/268 250/281/268 235/266/268 +f 243/274/269 257/288/269 258/289/269 +f 235/266/270 251/282/270 236/267/270 +f 243/274/271 259/290/271 244/275/271 +f 237/268/272 251/282/272 252/283/272 +f 249/280/273 263/294/273 264/295/273 +f 256/287/274 272/303/274 257/288/274 +f 249/280/275 265/296/275 250/281/275 +f 258/289/276 272/303/276 273/304/276 +f 250/281/277 266/297/277 251/282/277 +f 258/289/278 274/305/278 259/290/278 +f 252/283/279 266/297/279 267/298/279 +f 260/291/280 274/305/280 275/306/280 +f 252/283/281 268/299/281 253/284/281 +f 260/291/282 276/307/282 261/292/282 +f 254/285/283 268/299/283 269/300/283 +f 261/292/284 277/308/284 262/293/284 +f 255/286/285 269/300/285 270/301/285 +f 248/279/286 82/99/286 263/294/286 +f 308/356/287 262/293/287 277/308/287 +f 255/286/288 271/302/288 256/287/288 +f 267/298/289 283/314/289 268/299/289 +f 275/306/290 291/322/290 276/307/290 +f 269/300/291 283/314/291 284/315/291 +f 277/308/292 291/322/292 292/323/292 +f 270/301/293 284/315/293 285/316/293 +f 263/294/294 82/100/294 278/309/294 +f 308/357/295 277/308/295 292/323/295 +f 270/301/296 286/317/296 271/302/296 +f 264/295/297 278/309/297 279/310/297 +f 271/302/298 287/318/298 272/303/298 +f 264/295/299 280/311/299 265/296/299 +f 273/304/300 287/318/300 288/319/300 +f 265/296/301 281/312/301 266/297/301 +f 273/304/302 289/320/302 274/305/302 +f 267/298/303 281/312/303 282/313/303 +f 275/306/304 289/320/304 290/321/304 +f 286/317/305 302/333/305 287/318/305 +f 279/310/306 295/326/306 280/311/306 +f 288/319/307 302/333/307 303/334/307 +f 280/311/308 296/327/308 281/312/308 +f 288/319/309 304/335/309 289/320/309 +f 282/313/310 296/327/310 297/328/310 +f 290/321/311 304/335/311 305/336/311 +f 282/313/312 298/329/312 283/314/312 +f 290/321/313 306/337/313 291/322/313 +f 284/315/314 298/329/314 299/330/314 +f 292/323/315 306/337/315 307/338/315 +f 285/316/316 299/330/316 300/331/316 +f 278/309/317 82/101/317 293/324/317 +f 308/358/318 292/323/318 307/338/318 +f 285/316/319 301/332/319 286/317/319 +f 278/309/320 294/325/320 279/310/320 +f 305/336/321 322/384/321 306/337/321 +f 299/330/322 314/376/322 315/377/322 +f 306/337/323 323/385/323 307/338/323 +f 300/331/324 315/377/324 316/378/324 +f 293/324/325 82/102/325 309/371/325 +f 308/359/326 307/338/326 323/385/326 +f 300/331/327 317/379/327 301/332/327 +f 293/324/328 310/372/328 294/325/328 +f 301/332/329 318/380/329 302/333/329 +f 294/325/330 311/373/330 295/326/330 +f 303/334/331 318/380/331 319/381/331 +f 295/326/332 312/374/332 296/327/332 +f 303/334/333 320/382/333 304/335/333 +f 297/328/334 312/374/334 313/375/334 +f 305/336/335 320/382/335 321/383/335 +f 297/328/336 314/376/336 298/329/336 +f 310/372/337 326/388/337 311/373/337 +f 319/381/338 333/395/338 334/396/338 +f 311/373/339 327/389/339 312/374/339 +f 319/381/340 335/397/340 320/382/340 +f 312/374/341 328/390/341 313/375/341 +f 321/383/342 335/397/342 336/398/342 +f 313/375/343 329/391/343 314/376/343 +f 321/383/344 337/399/344 322/384/344 +f 315/377/345 329/391/345 330/392/345 +f 322/384/346 338/400/346 323/385/346 +f 316/378/347 330/392/347 331/393/347 +f 309/371/348 82/103/348 324/386/348 +f 308/360/349 323/385/349 338/400/349 +f 316/378/350 332/394/350 317/379/350 +f 309/371/351 325/387/351 310/372/351 +f 317/379/352 333/395/352 318/380/352 +f 330/392/353 344/406/353 345/407/353 +f 337/399/354 353/415/354 338/400/354 +f 331/393/355 345/407/355 346/408/355 +f 324/386/356 82/104/356 339/401/356 +f 308/361/357 338/400/357 353/415/357 +f 331/393/358 347/409/358 332/394/358 +f 324/386/359 340/402/359 325/387/359 +f 332/394/360 348/410/360 333/395/360 +f 325/387/361 341/403/361 326/388/361 +f 334/396/362 348/410/362 349/411/362 +f 326/388/363 342/404/363 327/389/363 +f 334/396/364 350/412/364 335/397/364 +f 328/390/365 342/404/365 343/405/365 +f 336/398/366 350/412/366 351/413/366 +f 328/390/367 344/406/367 329/391/367 +f 336/398/368 352/414/368 337/399/368 +f 349/411/369 363/434/369 364/436/369 +f 341/403/370 357/422/370 342/404/370 +f 349/411/371 365/438/371 350/412/371 +f 343/405/372 357/422/372 358/424/372 +f 351/413/373 365/438/373 366/440/373 +f 343/405/374 359/426/374 344/406/374 +f 351/413/375 367/442/375 352/414/375 +f 345/407/376 359/426/376 360/428/376 +f 352/414/377 368/445/377 353/415/377 +f 346/408/378 360/428/378 361/430/378 +f 339/401/379 82/105/379 354/416/379 +f 308/362/380 353/415/380 368/445/380 +f 346/408/381 362/432/381 347/409/381 +f 339/401/382 355/418/382 340/402/382 +f 347/409/383 363/434/383 348/410/383 +f 341/403/384 355/418/384 356/420/384 +f 367/443/385 383/460/385 368/444/385 +f 361/431/386 375/452/386 376/453/386 +f 354/417/387 82/106/387 369/446/387 +f 308/363/388 368/444/388 383/460/388 +f 361/431/389 377/454/389 362/433/389 +f 354/417/390 370/447/390 355/419/390 +f 362/433/391 378/455/391 363/435/391 +f 356/421/392 370/447/392 371/448/392 +f 364/437/393 378/455/393 379/456/393 +f 356/421/394 372/449/394 357/423/394 +f 364/437/395 380/457/395 365/439/395 +f 358/425/396 372/449/396 373/450/396 +f 366/441/397 380/457/397 381/458/397 +f 358/425/398 374/451/398 359/427/398 +f 366/441/399 382/459/399 367/443/399 +f 360/429/400 374/451/400 375/452/400 +f 379/456/401 395/472/401 380/457/401 +f 373/450/402 387/464/402 388/465/402 +f 381/458/403 395/472/403 396/473/403 +f 373/450/404 389/466/404 374/451/404 +f 381/458/405 397/474/405 382/459/405 +f 375/452/406 389/466/406 390/467/406 +f 382/459/407 398/475/407 383/460/407 +f 376/453/408 390/467/408 391/468/408 +f 369/446/409 82/107/409 384/461/409 +f 308/364/410 383/460/410 398/475/410 +f 376/453/411 392/469/411 377/454/411 +f 369/446/412 385/462/412 370/447/412 +f 377/454/413 393/470/413 378/455/413 +f 371/448/414 385/462/414 386/463/414 +f 379/456/415 393/470/415 394/471/415 +f 371/448/416 387/464/416 372/449/416 +f 384/461/417 82/108/417 399/476/417 +f 308/365/418 398/475/418 413/490/418 +f 391/468/419 407/484/419 392/469/419 +f 385/462/420 399/476/420 400/477/420 +f 392/469/421 408/485/421 393/470/421 +f 385/462/422 401/478/422 386/463/422 +f 394/471/423 408/485/423 409/486/423 +f 386/463/424 402/479/424 387/464/424 +f 394/471/425 410/487/425 395/472/425 +f 388/465/426 402/479/426 403/480/426 +f 396/473/427 410/487/427 411/488/427 +f 388/465/428 404/481/428 389/466/428 +f 397/474/429 411/488/429 412/489/429 +f 390/467/430 404/481/430 405/482/430 +f 397/474/431 413/490/431 398/475/431 +f 391/468/432 405/482/432 406/483/432 +f 403/480/433 417/494/433 418/495/433 +f 411/488/434 425/502/434 426/503/434 +f 403/480/435 419/496/435 404/481/435 +f 411/488/436 427/504/436 412/489/436 +f 405/482/437 419/496/437 420/497/437 +f 412/489/438 428/505/438 413/490/438 +f 406/483/439 420/497/439 421/498/439 +f 399/476/440 82/109/440 414/491/440 +f 308/366/441 413/490/441 428/505/441 +f 406/483/442 422/499/442 407/484/442 +f 399/476/443 415/492/443 400/477/443 +f 407/484/444 423/500/444 408/485/444 +f 401/478/445 415/492/445 416/493/445 +f 409/486/446 423/500/446 424/501/446 +f 401/478/447 417/494/447 402/479/447 +f 409/486/448 425/502/448 410/487/448 +f 421/498/449 437/514/449 422/499/449 +f 414/491/450 430/507/450 415/492/450 +f 422/499/451 438/515/451 423/500/451 +f 416/493/452 430/507/452 431/508/452 +f 424/501/453 438/515/453 439/516/453 +f 416/493/454 432/509/454 417/494/454 +f 424/501/455 440/517/455 425/502/455 +f 418/495/456 432/509/456 433/510/456 +f 426/503/457 440/517/457 441/518/457 +f 418/495/458 434/511/458 419/496/458 +f 426/503/459 442/519/459 427/504/459 +f 420/497/460 434/511/460 435/512/460 +f 427/504/461 443/520/461 428/505/461 +f 421/498/462 435/512/462 436/513/462 +f 414/491/463 82/110/463 429/506/463 +f 308/367/464 428/505/464 443/520/464 +f 441/518/465 455/532/465 456/533/465 +f 433/510/466 449/526/466 434/511/466 +f 441/518/467 457/534/467 442/519/467 +f 435/512/468 449/526/468 450/527/468 +f 442/519/469 458/535/469 443/520/469 +f 436/513/470 450/527/470 451/528/470 +f 429/506/471 82/111/471 444/521/471 +f 308/368/472 443/520/472 458/535/472 +f 436/513/473 452/529/473 437/514/473 +f 430/507/474 444/521/474 445/522/474 +f 437/514/475 453/530/475 438/515/475 +f 430/507/476 446/523/476 431/508/476 +f 439/516/477 453/530/477 454/531/477 +f 431/508/478 447/524/478 432/509/478 +f 439/516/479 455/532/479 440/517/479 +f 433/510/480 447/524/480 448/525/480 +f 444/521/481 460/537/481 445/522/481 +f 452/529/482 468/545/482 453/530/482 +f 446/523/483 460/537/483 461/538/483 +f 454/531/484 468/545/484 469/546/484 +f 446/523/485 462/539/485 447/524/485 +f 454/531/486 470/547/486 455/532/486 +f 448/525/487 462/539/487 463/540/487 +f 456/533/488 470/547/488 471/548/488 +f 448/525/489 464/541/489 449/526/489 +f 456/533/490 472/549/490 457/534/490 +f 450/527/491 464/541/491 465/542/491 +f 458/535/492 472/549/492 473/550/492 +f 451/528/493 465/542/493 466/543/493 +f 444/521/494 82/112/494 459/536/494 +f 308/369/495 458/535/495 473/550/495 +f 451/528/496 467/544/496 452/529/496 +f 464/541/497 2/2/497 477/554/497 +f 471/548/498 481/558/498 472/549/498 +f 465/542/499 477/554/499 3/3/499 +f 472/549/500 482/559/500 473/550/500 +f 466/543/501 3/3/501 4/4/501 +f 459/536/502 82/113/502 474/551/502 +f 308/370/503 473/550/503 482/559/503 +f 466/543/504 5/5/504 467/544/504 +f 460/537/505 474/551/505 475/552/505 +f 467/544/506 478/555/506 468/545/506 +f 461/538/507 475/552/507 1/1/507 +f 468/545/508 6/6/508 469/546/508 +f 462/539/509 1/1/509 476/553/509 +f 469/546/510 479/556/510 470/547/510 +f 463/540/511 476/553/511 2/2/511 +f 471/548/512 479/556/512 480/557/512 +f 479/556/1 18/18/1 19/19/1 +f 477/554/2 2/2/2 11/11/2 +f 480/557/3 19/19/3 20/20/3 +f 3/3/4 477/554/4 12/12/4 +f 481/558/5 20/20/5 21/21/5 +f 3/3/513 13/13/513 14/14/513 +f 4/4/514 14/14/514 15/15/514 +f 475/552/10 474/551/10 7/7/10 +f 5/5/11 15/15/11 16/16/11 +f 1/1/12 475/552/12 8/8/12 +f 478/555/13 16/16/13 17/17/13 +f 476/553/14 1/1/14 9/9/14 +f 6/6/15 17/17/15 18/18/15 +f 2/2/16 476/553/16 10/10/16 +f 17/17/17 32/32/17 33/33/17 +f 10/10/18 25/25/18 26/26/18 +f 19/19/19 18/18/19 33/33/19 +f 11/11/20 26/26/20 27/27/20 +f 20/20/21 19/19/21 34/34/21 +f 13/13/22 12/12/22 27/27/22 +f 20/20/23 35/35/23 36/36/23 +f 13/13/24 28/28/24 29/29/24 +f 14/14/27 29/29/27 30/30/27 +f 7/7/28 22/22/28 23/23/28 +f 15/15/29 30/30/29 31/31/29 +f 8/8/30 23/23/30 24/24/30 +f 16/16/31 31/31/31 32/32/31 +f 9/9/32 24/24/32 25/25/32 +f 30/30/35 29/29/35 44/44/35 +f 22/22/36 37/37/36 38/38/36 +f 30/30/37 45/45/37 46/46/37 +f 23/23/515 38/38/515 39/39/515 +f 32/32/39 31/31/39 46/46/39 +f 24/24/40 39/39/40 40/40/40 +f 33/33/41 32/32/41 47/47/41 +f 25/25/42 40/40/42 41/41/42 +f 34/34/43 33/33/43 48/48/43 +f 26/26/44 41/41/44 42/42/44 +f 34/34/516 49/49/516 50/50/516 +f 27/27/46 42/42/46 43/43/46 +f 35/35/47 50/50/47 51/51/47 +f 28/28/48 43/43/48 44/44/48 +f 40/40/49 55/55/49 56/56/49 +f 48/48/50 63/63/50 64/64/50 +f 41/41/51 56/56/51 57/57/51 +f 49/49/52 64/64/52 65/65/52 +f 43/43/53 42/42/53 57/57/53 +f 50/50/54 65/65/54 66/66/54 +f 44/44/55 43/43/55 58/58/55 +f 44/44/58 59/59/58 60/60/58 +f 37/37/59 52/52/59 53/53/59 +f 45/45/60 60/60/60 61/61/60 +f 38/38/61 53/53/61 54/54/61 +f 47/47/62 46/46/62 61/61/62 +f 39/39/63 54/54/63 55/55/63 +f 47/47/64 62/62/64 63/63/64 +f 59/59/65 74/74/65 75/75/65 +f 52/52/66 67/67/66 68/68/66 +f 60/60/67 75/75/67 76/76/67 +f 53/53/68 68/68/68 69/69/68 +f 62/62/69 61/61/69 76/76/69 +f 54/54/70 69/69/70 70/70/70 +f 62/62/71 77/77/71 78/78/71 +f 56/56/72 55/55/72 70/70/72 +f 63/63/73 78/78/73 79/79/73 +f 56/56/74 71/71/74 72/72/74 +f 65/65/75 64/64/75 79/79/75 +f 58/58/76 57/57/76 72/72/76 +f 65/65/517 80/80/517 81/81/517 +f 59/59/78 58/58/78 73/73/78 +f 78/78/81 94/125/81 95/126/81 +f 71/71/82 87/118/82 88/119/82 +f 79/79/83 95/126/83 96/127/83 +f 73/73/84 72/72/84 88/119/84 +f 81/81/85 80/80/85 96/127/85 +f 74/74/86 73/73/86 89/120/86 +f 74/74/89 90/121/89 91/122/89 +f 67/67/90 83/114/90 84/115/90 +f 75/75/91 91/122/91 92/123/91 +f 68/68/92 84/115/92 85/116/92 +f 77/77/93 76/76/93 92/123/93 +f 69/69/94 85/116/94 86/117/94 +f 77/77/95 93/124/95 94/125/95 +f 71/71/96 70/70/96 86/117/96 +f 91/122/97 106/137/97 107/138/97 +f 84/115/98 99/130/98 100/131/98 +f 93/124/99 92/123/99 107/138/99 +f 85/116/100 100/131/100 101/132/100 +f 93/124/101 108/139/101 109/140/101 +f 87/118/102 86/117/102 101/132/102 +f 95/126/103 94/125/103 109/140/103 +f 87/118/104 102/133/104 103/134/104 +f 96/127/105 95/126/105 110/141/105 +f 89/120/106 88/119/106 103/134/106 +f 96/127/107 111/142/107 112/143/107 +f 90/121/108 89/120/108 104/135/108 +f 90/121/111 105/136/111 106/137/111 +f 84/115/112 83/114/112 98/129/112 +f 110/141/113 125/156/113 126/157/113 +f 104/135/114 103/134/114 118/149/114 +f 111/142/115 126/157/115 127/158/115 +f 105/136/116 104/135/116 119/150/116 +f 105/136/119 120/151/119 121/152/119 +f 99/130/120 98/129/120 113/144/120 +f 106/137/121 121/152/121 122/153/121 +f 99/130/122 114/145/122 115/146/122 +f 108/139/123 107/138/123 122/153/123 +f 100/131/124 115/146/124 116/147/124 +f 108/139/125 123/154/125 124/155/125 +f 102/133/126 101/132/126 116/147/126 +f 110/141/127 109/140/127 124/155/127 +f 102/133/128 117/148/128 118/149/128 +f 114/145/129 129/160/129 130/161/129 +f 123/154/130 122/153/130 137/168/130 +f 115/146/131 130/161/131 131/162/131 +f 123/154/132 138/169/132 139/170/132 +f 117/148/133 116/147/133 131/162/133 +f 125/156/134 124/155/134 139/170/134 +f 117/148/135 132/163/135 133/164/135 +f 125/156/136 140/171/136 141/172/136 +f 119/150/137 118/149/137 133/164/137 +f 126/157/138 141/172/138 142/173/138 +f 120/151/139 119/150/139 134/165/139 +f 120/151/142 135/166/142 136/167/142 +f 113/144/143 128/159/143 129/160/143 +f 121/152/144 136/167/144 137/168/144 +f 134/165/145 133/164/145 148/179/145 +f 142/173/146 141/172/146 156/187/146 +f 135/166/147 134/165/147 149/180/147 +f 135/166/150 150/181/150 151/182/150 +f 128/159/151 143/174/151 144/175/151 +f 136/167/152 151/182/152 152/183/152 +f 130/161/153 129/160/153 144/175/153 +f 138/169/154 137/168/154 152/183/154 +f 130/161/155 145/176/155 146/177/155 +f 138/169/156 153/184/156 154/185/156 +f 132/163/157 131/162/157 146/177/157 +f 140/171/158 139/170/158 154/185/158 +f 132/163/159 147/178/159 148/179/159 +f 140/171/160 155/186/160 156/187/160 +f 153/184/161 152/183/161 167/198/161 +f 145/176/162 160/191/162 161/192/162 +f 153/184/163 168/199/163 169/200/163 +f 147/178/164 146/177/164 161/192/164 +f 155/186/165 154/185/165 169/200/165 +f 147/178/166 162/193/166 163/194/166 +f 155/186/518 170/201/518 171/202/518 +f 149/180/168 148/179/168 163/194/168 +f 156/187/169 171/202/169 172/203/169 +f 150/181/170 149/180/170 164/195/170 +f 150/181/173 165/196/173 166/197/173 +f 143/174/519 158/189/519 159/190/519 +f 151/182/175 166/197/175 167/198/175 +f 145/176/520 144/175/520 159/190/520 +f 172/203/177 171/202/177 186/217/177 +f 165/196/178 164/195/178 179/210/178 +f 165/196/181 180/211/181 181/212/181 +f 158/189/182 173/204/182 174/205/182 +f 166/197/183 181/212/183 182/213/183 +f 159/190/184 174/205/184 175/206/184 +f 168/199/185 167/198/185 182/213/185 +f 160/191/186 175/206/186 176/207/186 +f 168/199/187 183/214/187 184/215/187 +f 162/193/188 161/192/188 176/207/188 +f 169/200/189 184/215/189 185/216/189 +f 162/193/190 177/208/190 178/209/190 +f 171/202/191 170/201/191 185/216/191 +f 164/195/192 163/194/192 178/209/192 +f 175/206/193 190/221/193 191/222/193 +f 183/214/194 198/229/194 199/230/194 +f 177/208/195 176/207/195 191/222/195 +f 185/216/196 184/215/196 199/230/196 +f 177/208/197 192/223/197 193/224/197 +f 185/216/198 200/231/198 201/232/198 +f 179/210/199 178/209/199 193/224/199 +f 186/217/200 201/232/200 202/233/200 +f 180/211/201 179/210/201 194/225/201 +f 180/211/204 195/226/204 196/227/204 +f 174/205/205 173/204/205 188/219/205 +f 181/212/206 196/227/206 197/228/206 +f 175/206/207 174/205/207 189/220/207 +f 183/214/208 182/213/208 197/228/208 +f 195/226/209 194/225/209 209/240/209 +f 195/226/212 210/241/212 211/242/212 +f 188/219/213 203/234/213 204/235/213 +f 196/227/214 211/242/214 212/243/214 +f 189/220/215 204/235/215 205/236/215 +f 198/229/216 197/228/216 212/243/216 +f 190/221/217 205/236/217 206/237/217 +f 198/229/218 213/244/218 214/245/218 +f 192/223/219 191/222/219 206/237/219 +f 200/231/220 199/230/220 214/245/220 +f 192/223/221 207/238/221 208/239/221 +f 200/231/521 215/246/521 216/247/521 +f 194/225/223 193/224/223 208/239/223 +f 201/232/224 216/247/224 217/248/224 +f 213/244/225 228/259/225 229/260/225 +f 207/238/226 206/237/226 221/252/226 +f 215/246/227 214/245/227 229/260/227 +f 207/238/228 222/253/228 223/254/228 +f 215/246/229 230/261/229 231/262/229 +f 209/240/230 208/239/230 223/254/230 +f 216/247/231 231/262/231 232/263/231 +f 210/241/232 209/240/232 224/255/232 +f 210/241/235 225/256/235 226/257/235 +f 203/234/236 218/249/236 219/250/236 +f 211/242/237 226/257/237 227/258/237 +f 204/235/238 219/250/238 220/251/238 +f 213/244/239 212/243/239 227/258/239 +f 205/236/240 220/251/240 221/252/240 +f 225/256/242 240/271/242 241/272/242 +f 218/249/243 233/264/243 234/265/243 +f 226/257/244 241/272/244 242/273/244 +f 220/251/245 219/250/245 234/265/245 +f 228/259/246 227/258/246 242/273/246 +f 220/251/247 235/266/247 236/267/247 +f 228/259/248 243/274/248 244/275/248 +f 222/253/249 221/252/249 236/267/249 +f 230/261/250 229/260/250 244/275/250 +f 222/253/251 237/268/251 238/269/251 +f 230/261/252 245/276/252 246/277/252 +f 224/255/253 223/254/253 238/269/253 +f 232/263/254 231/262/254 246/277/254 +f 225/256/255 224/255/255 239/270/255 +f 245/276/257 244/275/257 259/290/257 +f 237/268/258 252/283/258 253/284/258 +f 245/276/259 260/291/259 261/292/259 +f 239/270/260 238/269/260 253/284/260 +f 246/277/261 261/292/261 262/293/261 +f 240/271/522 239/270/522 254/285/522 +f 240/271/523 255/286/523 256/287/523 +f 233/264/266 248/279/266 249/280/266 +f 241/272/267 256/287/267 257/288/267 +f 234/265/268 249/280/268 250/281/268 +f 243/274/269 242/273/269 257/288/269 +f 235/266/270 250/281/270 251/282/270 +f 243/274/271 258/289/271 259/290/271 +f 237/268/272 236/267/272 251/282/272 +f 249/280/273 248/279/273 263/294/273 +f 256/287/274 271/302/274 272/303/274 +f 249/280/275 264/295/275 265/296/275 +f 258/289/276 257/288/276 272/303/276 +f 250/281/277 265/296/277 266/297/277 +f 258/289/278 273/304/278 274/305/278 +f 252/283/279 251/282/279 266/297/279 +f 260/291/280 259/290/280 274/305/280 +f 252/283/281 267/298/281 268/299/281 +f 260/291/282 275/306/282 276/307/282 +f 254/285/283 253/284/283 268/299/283 +f 261/292/284 276/307/284 277/308/284 +f 255/286/285 254/285/285 269/300/285 +f 255/286/288 270/301/288 271/302/288 +f 267/298/289 282/313/289 283/314/289 +f 275/306/524 290/321/524 291/322/524 +f 269/300/291 268/299/291 283/314/291 +f 277/308/292 276/307/292 291/322/292 +f 270/301/293 269/300/293 284/315/293 +f 270/301/296 285/316/296 286/317/296 +f 264/295/297 263/294/297 278/309/297 +f 271/302/298 286/317/298 287/318/298 +f 264/295/525 279/310/525 280/311/525 +f 273/304/300 272/303/300 287/318/300 +f 265/296/301 280/311/301 281/312/301 +f 273/304/302 288/319/302 289/320/302 +f 267/298/303 266/297/303 281/312/303 +f 275/306/304 274/305/304 289/320/304 +f 286/317/305 301/332/305 302/333/305 +f 279/310/306 294/325/306 295/326/306 +f 288/319/307 287/318/307 302/333/307 +f 280/311/308 295/326/308 296/327/308 +f 288/319/309 303/334/309 304/335/309 +f 282/313/310 281/312/310 296/327/310 +f 290/321/311 289/320/311 304/335/311 +f 282/313/312 297/328/312 298/329/312 +f 290/321/313 305/336/313 306/337/313 +f 284/315/314 283/314/314 298/329/314 +f 292/323/315 291/322/315 306/337/315 +f 285/316/316 284/315/316 299/330/316 +f 285/316/319 300/331/319 301/332/319 +f 278/309/320 293/324/320 294/325/320 +f 305/336/321 321/383/321 322/384/321 +f 299/330/322 298/329/322 314/376/322 +f 306/337/526 322/384/526 323/385/526 +f 300/331/324 299/330/324 315/377/324 +f 300/331/327 316/378/327 317/379/327 +f 293/324/328 309/371/328 310/372/328 +f 301/332/329 317/379/329 318/380/329 +f 294/325/330 310/372/330 311/373/330 +f 303/334/331 302/333/331 318/380/331 +f 295/326/332 311/373/332 312/374/332 +f 303/334/333 319/381/333 320/382/333 +f 297/328/334 296/327/334 312/374/334 +f 305/336/335 304/335/335 320/382/335 +f 297/328/336 313/375/336 314/376/336 +f 310/372/337 325/387/337 326/388/337 +f 319/381/338 318/380/338 333/395/338 +f 311/373/339 326/388/339 327/389/339 +f 319/381/340 334/396/340 335/397/340 +f 312/374/341 327/389/341 328/390/341 +f 321/383/342 320/382/342 335/397/342 +f 313/375/343 328/390/343 329/391/343 +f 321/383/527 336/398/527 337/399/527 +f 315/377/345 314/376/345 329/391/345 +f 322/384/346 337/399/346 338/400/346 +f 316/378/347 315/377/347 330/392/347 +f 316/378/350 331/393/350 332/394/350 +f 309/371/351 324/386/351 325/387/351 +f 317/379/352 332/394/352 333/395/352 +f 330/392/353 329/391/353 344/406/353 +f 337/399/354 352/414/354 353/415/354 +f 331/393/355 330/392/355 345/407/355 +f 331/393/358 346/408/358 347/409/358 +f 324/386/359 339/401/359 340/402/359 +f 332/394/360 347/409/360 348/410/360 +f 325/387/361 340/402/361 341/403/361 +f 334/396/362 333/395/362 348/410/362 +f 326/388/363 341/403/363 342/404/363 +f 334/396/364 349/411/364 350/412/364 +f 328/390/365 327/389/365 342/404/365 +f 336/398/366 335/397/366 350/412/366 +f 328/390/367 343/405/367 344/406/367 +f 336/398/368 351/413/368 352/414/368 +f 349/411/369 348/410/369 363/434/369 +f 341/403/370 356/420/370 357/422/370 +f 349/411/371 364/436/371 365/438/371 +f 343/405/372 342/404/372 357/422/372 +f 351/413/373 350/412/373 365/438/373 +f 343/405/374 358/424/374 359/426/374 +f 351/413/375 366/440/375 367/442/375 +f 345/407/376 344/406/376 359/426/376 +f 352/414/377 367/442/377 368/445/377 +f 346/408/528 345/407/528 360/428/528 +f 346/408/529 361/430/529 362/432/529 +f 339/401/382 354/416/382 355/418/382 +f 347/409/383 362/432/383 363/434/383 +f 341/403/384 340/402/384 355/418/384 +f 367/443/385 382/459/385 383/460/385 +f 361/431/530 360/429/530 375/452/530 +f 361/431/531 376/453/531 377/454/531 +f 354/417/390 369/446/390 370/447/390 +f 362/433/391 377/454/391 378/455/391 +f 356/421/392 355/419/392 370/447/392 +f 364/437/393 363/435/393 378/455/393 +f 356/421/394 371/448/394 372/449/394 +f 364/437/395 379/456/395 380/457/395 +f 358/425/396 357/423/396 372/449/396 +f 366/441/397 365/439/397 380/457/397 +f 358/425/398 373/450/398 374/451/398 +f 366/441/399 381/458/399 382/459/399 +f 360/429/400 359/427/400 374/451/400 +f 379/456/401 394/471/401 395/472/401 +f 373/450/402 372/449/402 387/464/402 +f 381/458/403 380/457/403 395/472/403 +f 373/450/404 388/465/404 389/466/404 +f 381/458/405 396/473/405 397/474/405 +f 375/452/406 374/451/406 389/466/406 +f 382/459/407 397/474/407 398/475/407 +f 376/453/408 375/452/408 390/467/408 +f 376/453/411 391/468/411 392/469/411 +f 369/446/412 384/461/412 385/462/412 +f 377/454/413 392/469/413 393/470/413 +f 371/448/414 370/447/414 385/462/414 +f 379/456/415 378/455/415 393/470/415 +f 371/448/416 386/463/416 387/464/416 +f 391/468/419 406/483/419 407/484/419 +f 385/462/420 384/461/420 399/476/420 +f 392/469/421 407/484/421 408/485/421 +f 385/462/422 400/477/422 401/478/422 +f 394/471/423 393/470/423 408/485/423 +f 386/463/424 401/478/424 402/479/424 +f 394/471/425 409/486/425 410/487/425 +f 388/465/426 387/464/426 402/479/426 +f 396/473/427 395/472/427 410/487/427 +f 388/465/428 403/480/428 404/481/428 +f 397/474/429 396/473/429 411/488/429 +f 390/467/430 389/466/430 404/481/430 +f 397/474/431 412/489/431 413/490/431 +f 391/468/432 390/467/432 405/482/432 +f 403/480/433 402/479/433 417/494/433 +f 411/488/434 410/487/434 425/502/434 +f 403/480/435 418/495/435 419/496/435 +f 411/488/436 426/503/436 427/504/436 +f 405/482/437 404/481/437 419/496/437 +f 412/489/438 427/504/438 428/505/438 +f 406/483/439 405/482/439 420/497/439 +f 406/483/442 421/498/442 422/499/442 +f 399/476/443 414/491/443 415/492/443 +f 407/484/444 422/499/444 423/500/444 +f 401/478/445 400/477/445 415/492/445 +f 409/486/446 408/485/446 423/500/446 +f 401/478/447 416/493/447 417/494/447 +f 409/486/448 424/501/448 425/502/448 +f 421/498/449 436/513/449 437/514/449 +f 414/491/450 429/506/450 430/507/450 +f 422/499/451 437/514/451 438/515/451 +f 416/493/452 415/492/452 430/507/452 +f 424/501/453 423/500/453 438/515/453 +f 416/493/454 431/508/454 432/509/454 +f 424/501/455 439/516/455 440/517/455 +f 418/495/456 417/494/456 432/509/456 +f 426/503/457 425/502/457 440/517/457 +f 418/495/458 433/510/458 434/511/458 +f 426/503/459 441/518/459 442/519/459 +f 420/497/460 419/496/460 434/511/460 +f 427/504/461 442/519/461 443/520/461 +f 421/498/462 420/497/462 435/512/462 +f 441/518/465 440/517/465 455/532/465 +f 433/510/466 448/525/466 449/526/466 +f 441/518/467 456/533/467 457/534/467 +f 435/512/468 434/511/468 449/526/468 +f 442/519/469 457/534/469 458/535/469 +f 436/513/470 435/512/470 450/527/470 +f 436/513/473 451/528/473 452/529/473 +f 430/507/474 429/506/474 444/521/474 +f 437/514/475 452/529/475 453/530/475 +f 430/507/476 445/522/476 446/523/476 +f 439/516/477 438/515/477 453/530/477 +f 431/508/478 446/523/478 447/524/478 +f 439/516/479 454/531/479 455/532/479 +f 433/510/480 432/509/480 447/524/480 +f 444/521/481 459/536/481 460/537/481 +f 452/529/482 467/544/482 468/545/482 +f 446/523/483 445/522/483 460/537/483 +f 454/531/484 453/530/484 468/545/484 +f 446/523/485 461/538/485 462/539/485 +f 454/531/486 469/546/486 470/547/486 +f 448/525/487 447/524/487 462/539/487 +f 456/533/488 455/532/488 470/547/488 +f 448/525/489 463/540/489 464/541/489 +f 456/533/490 471/548/490 472/549/490 +f 450/527/491 449/526/491 464/541/491 +f 458/535/492 457/534/492 472/549/492 +f 451/528/493 450/527/493 465/542/493 +f 451/528/496 466/543/496 467/544/496 +f 464/541/497 463/540/497 2/2/497 +f 471/548/498 480/557/498 481/558/498 +f 465/542/499 464/541/499 477/554/499 +f 472/549/500 481/558/500 482/559/500 +f 466/543/501 465/542/501 3/3/501 +f 466/543/504 4/4/504 5/5/504 +f 460/537/505 459/536/505 474/551/505 +f 467/544/506 5/5/506 478/555/506 +f 461/538/507 460/537/507 475/552/507 +f 468/545/508 478/555/508 6/6/508 +f 462/539/509 461/538/509 1/1/509 +f 469/546/510 6/6/510 479/556/510 +f 463/540/511 462/539/511 476/553/511 +f 471/548/512 470/547/512 479/556/512 diff --git a/scenes/meshes/cornell/smooth-ball.obj b/scenes/meshes/cornell/smooth-ball.obj new file mode 100644 index 0000000..d0fe31f --- /dev/null +++ b/scenes/meshes/cornell/smooth-ball.obj @@ -0,0 +1,2486 @@ +# Blender 3.5.1 +# www.blender.org +o Sphere +v 1.832444 2.774141 2.360829 +v 1.832444 2.498241 2.084930 +v 1.832444 2.137761 1.935614 +v 1.832444 1.942671 1.916400 +v 1.832444 1.747581 1.935614 +v 1.832444 1.387101 2.084930 +v 1.870504 2.923456 2.725058 +v 1.907102 2.866550 2.541070 +v 1.940830 2.774141 2.371505 +v 1.970393 2.649778 2.222880 +v 1.994655 2.498241 2.100907 +v 2.012684 2.325355 2.010272 +v 2.023785 2.137761 1.954460 +v 2.027534 1.942671 1.935614 +v 2.023785 1.747581 1.954460 +v 2.012684 1.559988 2.010272 +v 1.994655 1.387101 2.100907 +v 1.970393 1.235564 2.222880 +v 1.940830 1.111202 2.371505 +v 1.907102 1.018792 2.541070 +v 1.870504 0.961886 2.725058 +v 1.907102 2.923456 2.736160 +v 1.978890 2.866550 2.562846 +v 2.045051 2.774141 2.403120 +v 2.103042 2.649778 2.263118 +v 2.150633 2.498241 2.148222 +v 2.185997 2.325355 2.062846 +v 2.207774 2.137761 2.010272 +v 2.215127 1.942671 1.992520 +v 2.207774 1.747581 2.010272 +v 2.185997 1.559988 2.062846 +v 2.150633 1.387101 2.148222 +v 2.103042 1.235564 2.263118 +v 2.045051 1.111202 2.403120 +v 1.978890 1.018792 2.562846 +v 1.907102 0.961886 2.736160 +v 1.940830 2.923456 2.754188 +v 2.045051 2.866550 2.598210 +v 2.141102 2.774141 2.454460 +v 2.225291 2.649778 2.328462 +v 2.294384 2.498241 2.225058 +v 2.345724 2.325355 2.148222 +v 2.377339 2.137761 2.100907 +v 2.388014 1.942671 2.084930 +v 2.377339 1.747581 2.100907 +v 2.345724 1.559988 2.148222 +v 2.294384 1.387101 2.225058 +v 2.225291 1.235564 2.328462 +v 2.141102 1.111202 2.454460 +v 2.045051 1.018792 2.598210 +v 1.940830 0.961886 2.754188 +v 1.970393 2.923456 2.778450 +v 2.103042 2.866550 2.645802 +v 2.225291 2.774141 2.523552 +v 2.332444 2.649778 2.416400 +v 2.420382 2.498241 2.328462 +v 2.485725 2.325355 2.263118 +v 2.525964 2.137761 2.222880 +v 2.539551 1.942671 2.209293 +v 2.525964 1.747581 2.222880 +v 2.485725 1.559988 2.263118 +v 2.420382 1.387101 2.328462 +v 2.332444 1.235564 2.416400 +v 2.225291 1.111202 2.523552 +v 2.103042 1.018792 2.645802 +v 1.970393 0.961886 2.778450 +v 1.994655 2.923456 2.808013 +v 2.150633 2.866550 2.703792 +v 2.294384 2.774141 2.607742 +v 2.420382 2.649778 2.523552 +v 2.523785 2.498241 2.454460 +v 2.600621 2.325355 2.403120 +v 2.647937 2.137761 2.371505 +v 2.663913 1.942671 2.360830 +v 2.647937 1.747581 2.371505 +v 2.600621 1.559988 2.403120 +v 2.523785 1.387101 2.454460 +v 2.420382 1.235564 2.523552 +v 2.294384 1.111202 2.607742 +v 2.150633 1.018792 2.703792 +v 1.994655 0.961886 2.808013 +v 1.832444 2.942671 2.916400 +v 2.012684 2.923456 2.841742 +v 2.185997 2.866550 2.769953 +v 2.345724 2.774141 2.703792 +v 2.485725 2.649778 2.645802 +v 2.600621 2.498241 2.598210 +v 2.685997 2.325355 2.562846 +v 2.738571 2.137761 2.541070 +v 2.756323 1.942671 2.533716 +v 2.738571 1.747581 2.541070 +v 2.685997 1.559988 2.562846 +v 2.600621 1.387101 2.598210 +v 2.485725 1.235564 2.645802 +v 2.345724 1.111202 2.703792 +v 2.185997 1.018792 2.769953 +v 2.012684 0.961886 2.841742 +v 2.023785 2.923456 2.878340 +v 2.207774 2.866550 2.841742 +v 2.377339 2.774141 2.808013 +v 2.525964 2.649778 2.778450 +v 2.647937 2.498241 2.754188 +v 2.738571 2.325355 2.736160 +v 2.794383 2.137761 2.725058 +v 2.813229 1.942671 2.721310 +v 2.794383 1.747581 2.725058 +v 2.738571 1.559988 2.736160 +v 2.647937 1.387101 2.754188 +v 2.525964 1.235564 2.778450 +v 2.377339 1.111202 2.808013 +v 2.207774 1.018792 2.841742 +v 2.023785 0.961886 2.878340 +v 2.027534 2.923456 2.916400 +v 2.215127 2.866550 2.916400 +v 2.388014 2.774141 2.916400 +v 2.539550 2.649778 2.916400 +v 2.663913 2.498241 2.916400 +v 2.756323 2.325355 2.916400 +v 2.813229 2.137761 2.916400 +v 2.832443 1.942671 2.916400 +v 2.813229 1.747581 2.916400 +v 2.756323 1.559988 2.916400 +v 2.663913 1.387101 2.916400 +v 2.539550 1.235564 2.916400 +v 2.388014 1.111202 2.916400 +v 2.215127 1.018792 2.916400 +v 2.027534 0.961886 2.916400 +v 2.023785 2.923456 2.954460 +v 2.207774 2.866550 2.991058 +v 2.377339 2.774141 3.024786 +v 2.525964 2.649778 3.054349 +v 2.647937 2.498241 3.078611 +v 2.738571 2.325355 3.096640 +v 2.794383 2.137761 3.107742 +v 2.813229 1.942671 3.111490 +v 2.794383 1.747581 3.107742 +v 2.738571 1.559988 3.096640 +v 2.647937 1.387101 3.078611 +v 2.525964 1.235564 3.054349 +v 2.377339 1.111202 3.024786 +v 2.207774 1.018792 2.991058 +v 2.023785 0.961886 2.954460 +v 2.012684 2.923456 2.991058 +v 2.185997 2.866550 3.062846 +v 2.345724 2.774141 3.129007 +v 2.485725 2.649778 3.186998 +v 2.600621 2.498241 3.234589 +v 2.685997 2.325355 3.269953 +v 2.738571 2.137761 3.291730 +v 2.756323 1.942671 3.299083 +v 2.738571 1.747581 3.291730 +v 2.685997 1.559988 3.269953 +v 2.600621 1.387101 3.234589 +v 2.485725 1.235564 3.186998 +v 2.345724 1.111202 3.129007 +v 2.185997 1.018792 3.062846 +v 2.012684 0.961886 2.991058 +v 1.994655 2.923456 3.024786 +v 2.150633 2.866550 3.129007 +v 2.294383 2.774141 3.225058 +v 2.420382 2.649778 3.309247 +v 2.523785 2.498241 3.378339 +v 2.600621 2.325355 3.429680 +v 2.647937 2.137761 3.461295 +v 2.663913 1.942671 3.471970 +v 2.647937 1.747581 3.461295 +v 2.600621 1.559988 3.429680 +v 2.523785 1.387101 3.378339 +v 2.420382 1.235564 3.309247 +v 2.294383 1.111202 3.225058 +v 2.150633 1.018792 3.129007 +v 1.994655 0.961886 3.024786 +v 1.970393 2.923456 3.054349 +v 2.103042 2.866550 3.186998 +v 2.225291 2.774141 3.309247 +v 2.332444 2.649778 3.416400 +v 2.420381 2.498241 3.504337 +v 2.485725 2.325355 3.569681 +v 2.525963 2.137761 3.609920 +v 2.539550 1.942671 3.623506 +v 2.525963 1.747581 3.609920 +v 2.485725 1.559988 3.569681 +v 2.420381 1.387101 3.504337 +v 2.332444 1.235564 3.416400 +v 2.225291 1.111202 3.309247 +v 2.103042 1.018792 3.186998 +v 1.970393 0.961886 3.054349 +v 1.940830 2.923456 3.078611 +v 2.045051 2.866550 3.234589 +v 2.141102 2.774141 3.378339 +v 2.225291 2.649778 3.504337 +v 2.294383 2.498241 3.607741 +v 2.345724 2.325355 3.684577 +v 2.377339 2.137761 3.731893 +v 2.388013 1.942671 3.747869 +v 2.377339 1.747581 3.731893 +v 2.345724 1.559988 3.684577 +v 2.294383 1.387101 3.607741 +v 2.225291 1.235564 3.504337 +v 2.141102 1.111202 3.378339 +v 2.045051 1.018792 3.234589 +v 1.940830 0.961886 3.078611 +v 1.907102 2.923456 3.096640 +v 1.978890 2.866550 3.269953 +v 2.045051 2.774141 3.429679 +v 2.103042 2.649778 3.569681 +v 2.150633 2.498241 3.684577 +v 2.185997 2.325355 3.769953 +v 2.207774 2.137761 3.822527 +v 2.215127 1.942671 3.840279 +v 2.207774 1.747581 3.822527 +v 2.185997 1.559988 3.769953 +v 2.150633 1.387101 3.684577 +v 2.103042 1.235564 3.569681 +v 2.045051 1.111202 3.429679 +v 1.978890 1.018792 3.269953 +v 1.907102 0.961886 3.096640 +v 1.870504 2.923456 3.107741 +v 1.907102 2.866550 3.291730 +v 1.940830 2.774141 3.461295 +v 1.970393 2.649778 3.609920 +v 1.994655 2.498241 3.731893 +v 2.012684 2.325355 3.822527 +v 2.023785 2.137761 3.878339 +v 2.027534 1.942671 3.897184 +v 2.023785 1.747581 3.878339 +v 2.012684 1.559988 3.822527 +v 1.994655 1.387101 3.731893 +v 1.970393 1.235564 3.609920 +v 1.940830 1.111202 3.461295 +v 1.907102 1.018792 3.291730 +v 1.870504 0.961886 3.107741 +v 1.832444 2.923456 3.111490 +v 1.832444 2.866550 3.299083 +v 1.832444 2.774141 3.471970 +v 1.832444 2.649778 3.623506 +v 1.832444 2.498241 3.747869 +v 1.832444 2.325355 3.840279 +v 1.832444 2.137761 3.897185 +v 1.832443 1.942671 3.916399 +v 1.832444 1.747581 3.897185 +v 1.832444 1.559988 3.840279 +v 1.832444 1.387101 3.747869 +v 1.832444 1.235564 3.623506 +v 1.832444 1.111202 3.471970 +v 1.832444 1.018792 3.299083 +v 1.832444 0.961886 3.111490 +v 1.794384 2.923456 3.107741 +v 1.757786 2.866550 3.291730 +v 1.724057 2.774141 3.461295 +v 1.694494 2.649778 3.609920 +v 1.670232 2.498241 3.731893 +v 1.652204 2.325355 3.822527 +v 1.641102 2.137761 3.878339 +v 1.637353 1.942671 3.897184 +v 1.641102 1.747581 3.878339 +v 1.652204 1.559988 3.822527 +v 1.670232 1.387101 3.731893 +v 1.694494 1.235564 3.609920 +v 1.724057 1.111202 3.461295 +v 1.757786 1.018792 3.291730 +v 1.794384 0.961886 3.107741 +v 1.757786 2.923456 3.096640 +v 1.685997 2.866550 3.269953 +v 1.619836 2.774141 3.429679 +v 1.561846 2.649778 3.569681 +v 1.514254 2.498241 3.684577 +v 1.478890 2.325355 3.769953 +v 1.457114 2.137761 3.822527 +v 1.449760 1.942671 3.840278 +v 1.457114 1.747581 3.822527 +v 1.478890 1.559988 3.769953 +v 1.514254 1.387101 3.684577 +v 1.561846 1.235564 3.569681 +v 1.619836 1.111202 3.429679 +v 1.685997 1.018792 3.269953 +v 1.757786 0.961886 3.096640 +v 1.724057 2.923456 3.078611 +v 1.619836 2.866550 3.234589 +v 1.523786 2.774141 3.378339 +v 1.439596 2.649778 3.504337 +v 1.370504 2.498241 3.607741 +v 1.319164 2.325355 3.684577 +v 1.287549 2.137761 3.731893 +v 1.276874 1.942671 3.747869 +v 1.287549 1.747581 3.731893 +v 1.319164 1.559988 3.684577 +v 1.370504 1.387101 3.607741 +v 1.439596 1.235564 3.504337 +v 1.523786 1.111202 3.378339 +v 1.619836 1.018792 3.234589 +v 1.724057 0.961886 3.078611 +v 1.694494 2.923456 3.054349 +v 1.561846 2.866550 3.186998 +v 1.439596 2.774141 3.309247 +v 1.332444 2.649778 3.416399 +v 1.244506 2.498241 3.504337 +v 1.179163 2.325355 3.569681 +v 1.138924 2.137761 3.609919 +v 1.125337 1.942671 3.623506 +v 1.138924 1.747581 3.609919 +v 1.179163 1.559988 3.569681 +v 1.244506 1.387101 3.504337 +v 1.332444 1.235564 3.416399 +v 1.439596 1.111202 3.309247 +v 1.561846 1.018792 3.186998 +v 1.694494 0.961886 3.054349 +v 1.832444 0.942671 2.916400 +v 1.670232 2.923456 3.024786 +v 1.514254 2.866550 3.129007 +v 1.370504 2.774141 3.225058 +v 1.244506 2.649778 3.309247 +v 1.141102 2.498241 3.378339 +v 1.064266 2.325355 3.429679 +v 1.016951 2.137761 3.461294 +v 1.000975 1.942671 3.471969 +v 1.016951 1.747581 3.461294 +v 1.064266 1.559988 3.429679 +v 1.141102 1.387101 3.378339 +v 1.244506 1.235564 3.309247 +v 1.370504 1.111202 3.225058 +v 1.514254 1.018792 3.129007 +v 1.670232 0.961886 3.024786 +v 1.652204 2.923456 2.991057 +v 1.478890 2.866550 3.062846 +v 1.319164 2.774141 3.129007 +v 1.179162 2.649778 3.186998 +v 1.064266 2.498241 3.234589 +v 0.978891 2.325355 3.269953 +v 0.926317 2.137761 3.291730 +v 0.908565 1.942671 3.299082 +v 0.926317 1.747581 3.291730 +v 0.978891 1.559988 3.269953 +v 1.064266 1.387101 3.234589 +v 1.179162 1.235564 3.186998 +v 1.319164 1.111202 3.129007 +v 1.478890 1.018792 3.062846 +v 1.652204 0.961886 2.991057 +v 1.641102 2.923456 2.954460 +v 1.457114 2.866550 2.991057 +v 1.287549 2.774141 3.024786 +v 1.138924 2.649778 3.054349 +v 1.016951 2.498241 3.078611 +v 0.926317 2.325355 3.096640 +v 0.870504 2.137761 3.107741 +v 0.851659 1.942671 3.111489 +v 0.870504 1.747581 3.107741 +v 0.926317 1.559988 3.096640 +v 1.016951 1.387101 3.078611 +v 1.138924 1.235564 3.054349 +v 1.287549 1.111202 3.024786 +v 1.457114 1.018792 2.991057 +v 1.641102 0.961886 2.954460 +v 1.637354 2.923456 2.916400 +v 1.449760 2.866550 2.916400 +v 1.276874 2.774141 2.916399 +v 1.125337 2.649778 2.916400 +v 1.000975 2.498241 2.916399 +v 0.908565 2.325355 2.916400 +v 0.851659 2.137761 2.916399 +v 0.832445 1.942671 2.916399 +v 0.851659 1.747581 2.916399 +v 0.908565 1.559988 2.916400 +v 1.000975 1.387101 2.916399 +v 1.125337 1.235564 2.916400 +v 1.276874 1.111202 2.916399 +v 1.449760 1.018792 2.916400 +v 1.637354 0.961886 2.916400 +v 1.641102 2.923456 2.878340 +v 1.457114 2.866550 2.841742 +v 1.287549 2.774141 2.808013 +v 1.138924 2.649778 2.778450 +v 1.016951 2.498241 2.754188 +v 0.926317 2.325355 2.736160 +v 0.870504 2.137761 2.725058 +v 0.851659 1.942671 2.721309 +v 0.870504 1.747581 2.725058 +v 0.926317 1.559988 2.736160 +v 1.016951 1.387101 2.754188 +v 1.138924 1.235564 2.778450 +v 1.287549 1.111202 2.808013 +v 1.457114 1.018792 2.841742 +v 1.641102 0.961886 2.878340 +v 1.652204 2.923456 2.841742 +v 1.478891 2.866550 2.769953 +v 1.319164 2.774141 2.703792 +v 1.179163 2.649778 2.645802 +v 1.064266 2.498241 2.598210 +v 0.978891 2.325355 2.562846 +v 0.926317 2.137761 2.541070 +v 0.908565 1.942671 2.533716 +v 0.926317 1.747581 2.541070 +v 0.978891 1.559988 2.562846 +v 1.064266 1.387101 2.598210 +v 1.179163 1.235564 2.645802 +v 1.319164 1.111202 2.703792 +v 1.478891 1.018792 2.769953 +v 1.652204 0.961886 2.841742 +v 1.670232 2.923456 2.808013 +v 1.514254 2.866550 2.703792 +v 1.370504 2.774141 2.607742 +v 1.244506 2.649778 2.523552 +v 1.141103 2.498241 2.454460 +v 1.064266 2.325355 2.403120 +v 1.016951 2.137761 2.371505 +v 1.000975 1.942671 2.360830 +v 1.016951 1.747581 2.371505 +v 1.064266 1.559988 2.403120 +v 1.141103 1.387101 2.454460 +v 1.244506 1.235564 2.523552 +v 1.370504 1.111202 2.607742 +v 1.514254 1.018792 2.703792 +v 1.670232 0.961886 2.808013 +v 1.694494 2.923456 2.778450 +v 1.561846 2.866550 2.645802 +v 1.439597 2.774141 2.523552 +v 1.332444 2.649778 2.416400 +v 1.244506 2.498241 2.328462 +v 1.179163 2.325355 2.263119 +v 1.138924 2.137761 2.222880 +v 1.125338 1.942671 2.209293 +v 1.138924 1.747581 2.222880 +v 1.179163 1.559988 2.263119 +v 1.244506 1.387101 2.328462 +v 1.332444 1.235564 2.416400 +v 1.439597 1.111202 2.523552 +v 1.561846 1.018792 2.645802 +v 1.694494 0.961886 2.778450 +v 1.724057 2.923456 2.754188 +v 1.619836 2.866550 2.598210 +v 1.523786 2.774141 2.454460 +v 1.439596 2.649778 2.328462 +v 1.370504 2.498241 2.225058 +v 1.319164 2.325355 2.148222 +v 1.287549 2.137761 2.100907 +v 1.276875 1.942671 2.084931 +v 1.287549 1.747581 2.100907 +v 1.319164 1.559988 2.148222 +v 1.370504 1.387101 2.225058 +v 1.439596 1.235564 2.328462 +v 1.523786 1.111202 2.454460 +v 1.619836 1.018792 2.598210 +v 1.724057 0.961886 2.754188 +v 1.757786 2.923456 2.736160 +v 1.685997 2.866550 2.562846 +v 1.619837 2.774141 2.403120 +v 1.561846 2.649778 2.263118 +v 1.514255 2.498241 2.148222 +v 1.478891 2.325355 2.062847 +v 1.457114 2.137761 2.010273 +v 1.449761 1.942671 1.992521 +v 1.457114 1.747581 2.010273 +v 1.478891 1.559988 2.062847 +v 1.514255 1.387101 2.148222 +v 1.561846 1.235564 2.263118 +v 1.619837 1.111202 2.403120 +v 1.685997 1.018792 2.562846 +v 1.757786 0.961886 2.736160 +v 1.794384 2.923456 2.725058 +v 1.757786 2.866550 2.541070 +v 1.724058 2.774141 2.371505 +v 1.694494 2.649778 2.222880 +v 1.670232 2.498241 2.100907 +v 1.652204 2.325355 2.010273 +v 1.641102 2.137761 1.954461 +v 1.637354 1.942671 1.935616 +v 1.641102 1.747581 1.954461 +v 1.652204 1.559988 2.010273 +v 1.670232 1.387101 2.100907 +v 1.694494 1.235564 2.222880 +v 1.724058 1.111202 2.371505 +v 1.757786 1.018792 2.541070 +v 1.794384 0.961886 2.725058 +v 1.832444 2.923456 2.721310 +v 1.832444 2.866550 2.533716 +v 1.832444 2.649778 2.209293 +v 1.832444 2.325355 1.992521 +v 1.832444 1.559988 1.992521 +v 1.832444 1.235564 2.209293 +v 1.832444 1.111202 2.360830 +v 1.832444 1.018792 2.533716 +v 1.832444 0.961886 2.721310 +vn -0.0000 -0.7041 -0.7101 +vn 0.1092 -0.8286 -0.5490 +vn -0.0000 -0.8286 -0.5598 +vn -0.0000 0.3805 -0.9248 +vn 0.1626 0.5528 -0.8173 +vn 0.1804 0.3805 -0.9070 +vn 0.0757 -0.9217 -0.3804 +vn -0.0000 -0.9217 -0.3879 +vn -0.0000 0.1939 -0.9810 +vn 0.1914 0.1939 -0.9622 +vn 0.0392 -0.9796 -0.1971 +vn -0.0000 -0.9796 -0.2010 +vn 0.1951 -0.0000 -0.9808 +vn -0.0000 -0.0000 -1.0000 +vn -0.0000 0.9796 -0.2010 +vn -0.0000 1.0000 -0.0000 +vn 0.0392 0.9796 -0.1971 +vn -0.0000 -1.0000 -0.0000 +vn 0.1914 -0.1939 -0.9622 +vn -0.0000 -0.1939 -0.9810 +vn -0.0000 0.9217 -0.3879 +vn 0.0757 0.9217 -0.3804 +vn 0.1804 -0.3805 -0.9070 +vn -0.0000 -0.3805 -0.9248 +vn -0.0000 0.8286 -0.5598 +vn 0.1092 0.8286 -0.5490 +vn 0.1626 -0.5528 -0.8173 +vn -0.0000 -0.5528 -0.8333 +vn -0.0000 0.7041 -0.7101 +vn 0.1385 0.7041 -0.6965 +vn 0.1385 -0.7041 -0.6965 +vn -0.0000 0.5528 -0.8333 +vn 0.2718 -0.7041 -0.6561 +vn 0.3189 0.5528 -0.7699 +vn 0.2142 -0.8286 -0.5172 +vn 0.3539 0.3805 -0.8544 +vn 0.1484 -0.9217 -0.3584 +vn 0.3754 0.1939 -0.9063 +vn 0.0769 -0.9796 -0.1857 +vn 0.3827 -0.0000 -0.9239 +vn 0.0769 0.9796 -0.1857 +vn 0.3754 -0.1939 -0.9063 +vn 0.1484 0.9217 -0.3584 +vn 0.3539 -0.3805 -0.8544 +vn 0.2142 0.8286 -0.5172 +vn 0.3189 -0.5528 -0.7699 +vn 0.2718 0.7041 -0.6561 +vn 0.1117 0.9796 -0.1671 +vn 0.1117 -0.9796 -0.1671 +vn 0.5556 -0.0000 -0.8315 +vn 0.5450 -0.1939 -0.8157 +vn 0.2155 0.9217 -0.3225 +vn 0.5138 -0.3805 -0.7689 +vn 0.3110 0.8286 -0.4654 +vn 0.4630 -0.5528 -0.6929 +vn 0.3945 0.7041 -0.5905 +vn 0.3945 -0.7041 -0.5905 +vn 0.4630 0.5528 -0.6929 +vn 0.3110 -0.8286 -0.4654 +vn 0.5138 0.3805 -0.7689 +vn 0.2155 -0.9217 -0.3225 +vn 0.5450 0.1939 -0.8157 +vn 0.5893 0.5528 -0.5893 +vn 0.3958 -0.8286 -0.3958 +vn 0.6539 0.3805 -0.6539 +vn 0.2743 -0.9217 -0.2743 +vn 0.6937 0.1939 -0.6937 +vn 0.1421 -0.9796 -0.1421 +vn 0.7071 -0.0000 -0.7071 +vn 0.1421 0.9796 -0.1421 +vn 0.6937 -0.1939 -0.6937 +vn 0.2743 0.9217 -0.2743 +vn 0.6539 -0.3805 -0.6539 +vn 0.3958 0.8286 -0.3958 +vn 0.5893 -0.5528 -0.5893 +vn 0.5021 0.7041 -0.5021 +vn 0.5021 -0.7041 -0.5021 +vn 0.8157 -0.1939 -0.5450 +vn 0.3225 0.9217 -0.2155 +vn 0.7689 -0.3805 -0.5138 +vn 0.4654 0.8286 -0.3110 +vn 0.6929 -0.5528 -0.4630 +vn 0.5905 0.7041 -0.3945 +vn 0.5905 -0.7041 -0.3945 +vn 0.6929 0.5528 -0.4630 +vn 0.4654 -0.8286 -0.3110 +vn 0.7689 0.3805 -0.5138 +vn 0.3225 -0.9217 -0.2155 +vn 0.8157 0.1939 -0.5450 +vn 0.1671 -0.9796 -0.1117 +vn 0.8315 -0.0000 -0.5556 +vn 0.1671 0.9796 -0.1117 +vn 0.5172 -0.8286 -0.2142 +vn 0.8544 0.3805 -0.3539 +vn 0.3584 -0.9217 -0.1484 +vn 0.9063 0.1939 -0.3754 +vn 0.1857 -0.9796 -0.0769 +vn 0.9239 -0.0000 -0.3827 +vn 0.1857 0.9796 -0.0769 +vn 0.9063 -0.1939 -0.3754 +vn 0.3584 0.9217 -0.1484 +vn 0.8544 -0.3805 -0.3539 +vn 0.5172 0.8286 -0.2142 +vn 0.7699 -0.5528 -0.3189 +vn 0.6561 0.7041 -0.2718 +vn 0.6561 -0.7041 -0.2718 +vn 0.7699 0.5528 -0.3189 +vn 0.9070 -0.3805 -0.1804 +vn 0.5490 0.8286 -0.1092 +vn 0.8173 -0.5528 -0.1626 +vn 0.6965 0.7041 -0.1385 +vn 0.6965 -0.7041 -0.1385 +vn 0.8173 0.5528 -0.1626 +vn 0.5490 -0.8286 -0.1092 +vn 0.9070 0.3805 -0.1804 +vn 0.3804 -0.9217 -0.0757 +vn 0.9622 0.1939 -0.1914 +vn 0.1971 -0.9796 -0.0392 +vn 0.9808 -0.0000 -0.1951 +vn 0.1971 0.9796 -0.0392 +vn 0.9622 -0.1939 -0.1914 +vn 0.3804 0.9217 -0.0757 +vn 0.3879 -0.9217 -0.0000 +vn 0.9248 0.3805 -0.0000 +vn 0.9810 0.1939 -0.0000 +vn 0.2010 -0.9796 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn 0.2010 0.9796 -0.0000 +vn 0.9810 -0.1939 -0.0000 +vn 0.3879 0.9217 -0.0000 +vn 0.9248 -0.3805 -0.0000 +vn 0.5598 0.8286 -0.0000 +vn 0.8333 -0.5528 -0.0000 +vn 0.7101 0.7041 -0.0000 +vn 0.7101 -0.7041 -0.0000 +vn 0.8333 0.5528 -0.0000 +vn 0.5598 -0.8286 -0.0000 +vn 0.5490 0.8286 0.1092 +vn 0.9070 -0.3805 0.1804 +vn 0.8173 -0.5528 0.1626 +vn 0.6965 0.7041 0.1385 +vn 0.6965 -0.7041 0.1385 +vn 0.8173 0.5528 0.1626 +vn 0.5490 -0.8286 0.1092 +vn 0.9070 0.3805 0.1804 +vn 0.3804 -0.9217 0.0757 +vn 0.9622 0.1939 0.1914 +vn 0.1971 -0.9796 0.0392 +vn 0.9808 -0.0000 0.1951 +vn 0.1971 0.9796 0.0392 +vn 0.9622 -0.1939 0.1914 +vn 0.3804 0.9217 0.0757 +vn 0.8544 0.3805 0.3539 +vn 0.9063 0.1939 0.3754 +vn 0.3584 -0.9217 0.1484 +vn 0.1857 -0.9796 0.0769 +vn 0.9239 -0.0000 0.3827 +vn 0.1857 0.9796 0.0769 +vn 0.9063 -0.1939 0.3754 +vn 0.3584 0.9217 0.1484 +vn 0.8544 -0.3805 0.3539 +vn 0.5172 0.8286 0.2142 +vn 0.7699 -0.5528 0.3189 +vn 0.6561 0.7041 0.2718 +vn 0.6561 -0.7041 0.2718 +vn 0.7699 0.5528 0.3189 +vn 0.5172 -0.8286 0.2142 +vn 0.7689 -0.3805 0.5138 +vn 0.6929 -0.5528 0.4630 +vn 0.5905 0.7041 0.3945 +vn 0.5905 -0.7041 0.3945 +vn 0.6929 0.5528 0.4630 +vn 0.4654 -0.8286 0.3110 +vn 0.7689 0.3805 0.5138 +vn 0.3225 -0.9217 0.2155 +vn 0.8157 0.1939 0.5450 +vn 0.1671 -0.9796 0.1117 +vn 0.8315 -0.0000 0.5556 +vn 0.1671 0.9796 0.1117 +vn 0.8157 -0.1939 0.5450 +vn 0.3225 0.9217 0.2155 +vn 0.4654 0.8286 0.3110 +vn 0.2743 -0.9217 0.2743 +vn 0.1421 -0.9796 0.1421 +vn 0.6937 0.1939 0.6937 +vn 0.7071 -0.0000 0.7071 +vn 0.1421 0.9796 0.1421 +vn 0.6937 -0.1939 0.6937 +vn 0.2743 0.9217 0.2743 +vn 0.6539 -0.3805 0.6539 +vn 0.3958 0.8286 0.3958 +vn 0.5893 -0.5528 0.5893 +vn 0.5021 0.7041 0.5021 +vn 0.5021 -0.7041 0.5021 +vn 0.5893 0.5528 0.5893 +vn 0.3958 -0.8286 0.3958 +vn 0.6539 0.3805 0.6539 +vn 0.3945 0.7041 0.5905 +vn 0.3945 -0.7041 0.5905 +vn 0.4630 0.5528 0.6929 +vn 0.3110 -0.8286 0.4654 +vn 0.5138 0.3805 0.7689 +vn 0.2155 -0.9217 0.3225 +vn 0.5450 0.1939 0.8157 +vn 0.1117 -0.9796 0.1671 +vn 0.5556 -0.0000 0.8315 +vn 0.1117 0.9796 0.1671 +vn 0.5450 -0.1939 0.8157 +vn 0.2155 0.9217 0.3225 +vn 0.5138 -0.3805 0.7689 +vn 0.3110 0.8286 0.4654 +vn 0.4630 -0.5528 0.6929 +vn 0.3754 0.1939 0.9063 +vn 0.3827 -0.0000 0.9239 +vn 0.0769 0.9796 0.1857 +vn 0.0769 -0.9796 0.1857 +vn 0.3754 -0.1939 0.9063 +vn 0.1484 0.9217 0.3584 +vn 0.3539 -0.3805 0.8544 +vn 0.2142 0.8286 0.5172 +vn 0.3189 -0.5528 0.7699 +vn 0.2718 0.7041 0.6561 +vn 0.2718 -0.7041 0.6561 +vn 0.3189 0.5528 0.7699 +vn 0.2142 -0.8286 0.5172 +vn 0.3539 0.3805 0.8544 +vn 0.1484 -0.9217 0.3584 +vn 0.1385 -0.7041 0.6965 +vn 0.1385 0.7041 0.6965 +vn 0.1626 0.5528 0.8173 +vn 0.1092 -0.8286 0.5490 +vn 0.1804 0.3805 0.9070 +vn 0.0757 -0.9217 0.3804 +vn 0.1914 0.1939 0.9622 +vn 0.0392 -0.9796 0.1971 +vn 0.1951 -0.0000 0.9808 +vn 0.0392 0.9796 0.1971 +vn 0.1914 -0.1939 0.9622 +vn 0.0757 0.9217 0.3804 +vn 0.1804 -0.3805 0.9070 +vn 0.1092 0.8286 0.5490 +vn 0.1626 -0.5528 0.8173 +vn -0.0000 -0.9796 0.2010 +vn -0.0000 -0.1939 0.9810 +vn -0.0000 0.9217 0.3879 +vn -0.0000 -0.3805 0.9248 +vn -0.0000 0.8286 0.5598 +vn -0.0000 -0.5528 0.8333 +vn -0.0000 0.7041 0.7101 +vn -0.0000 -0.7041 0.7101 +vn -0.0000 0.5528 0.8333 +vn -0.0000 -0.8286 0.5598 +vn -0.0000 0.3805 0.9248 +vn -0.0000 -0.9217 0.3879 +vn -0.0000 0.1939 0.9810 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 0.9796 0.2010 +vn -0.1385 -0.7041 0.6965 +vn -0.1092 -0.8286 0.5490 +vn -0.1804 0.3805 0.9070 +vn -0.0757 -0.9217 0.3804 +vn -0.1914 0.1939 0.9622 +vn -0.0392 -0.9796 0.1971 +vn -0.1951 -0.0000 0.9808 +vn -0.0392 0.9796 0.1971 +vn -0.1914 -0.1939 0.9622 +vn -0.0757 0.9217 0.3804 +vn -0.1804 -0.3805 0.9070 +vn -0.1092 0.8286 0.5490 +vn -0.1626 -0.5528 0.8173 +vn -0.1385 0.7041 0.6965 +vn -0.1626 0.5528 0.8173 +vn -0.0769 0.9796 0.1857 +vn -0.1484 0.9217 0.3584 +vn -0.3539 -0.3805 0.8544 +vn -0.2142 0.8286 0.5172 +vn -0.3189 -0.5528 0.7699 +vn -0.2718 0.7041 0.6561 +vn -0.2718 -0.7041 0.6561 +vn -0.3189 0.5528 0.7699 +vn -0.2142 -0.8286 0.5172 +vn -0.3539 0.3805 0.8544 +vn -0.1484 -0.9217 0.3584 +vn -0.3754 0.1939 0.9063 +vn -0.0769 -0.9796 0.1857 +vn -0.3827 -0.0000 0.9239 +vn -0.3754 -0.1939 0.9063 +vn -0.5138 0.3805 0.7689 +vn -0.2155 -0.9217 0.3225 +vn -0.5450 0.1939 0.8157 +vn -0.1117 -0.9796 0.1671 +vn -0.5556 -0.0000 0.8315 +vn -0.1117 0.9796 0.1671 +vn -0.5450 -0.1939 0.8157 +vn -0.2155 0.9217 0.3225 +vn -0.5138 -0.3805 0.7689 +vn -0.3110 0.8286 0.4654 +vn -0.4630 -0.5528 0.6929 +vn -0.3945 0.7041 0.5905 +vn -0.3945 -0.7041 0.5905 +vn -0.4630 0.5528 0.6929 +vn -0.3110 -0.8286 0.4654 +vn -0.6539 -0.3805 0.6539 +vn -0.3958 0.8286 0.3958 +vn -0.5893 -0.5528 0.5893 +vn -0.5021 0.7041 0.5021 +vn -0.5021 -0.7041 0.5021 +vn -0.5893 0.5528 0.5893 +vn -0.3958 -0.8286 0.3958 +vn -0.6539 0.3805 0.6539 +vn -0.2743 -0.9217 0.2743 +vn -0.6937 0.1939 0.6937 +vn -0.1421 -0.9796 0.1421 +vn -0.7071 -0.0000 0.7071 +vn -0.1421 0.9796 0.1421 +vn -0.6937 -0.1939 0.6937 +vn -0.2743 0.9217 0.2743 +vn -0.3225 -0.9217 0.2155 +vn -0.7689 0.3805 0.5138 +vn -0.8157 0.1939 0.5450 +vn -0.1671 -0.9796 0.1117 +vn -0.8315 -0.0000 0.5556 +vn -0.1671 0.9796 0.1117 +vn -0.8157 -0.1939 0.5450 +vn -0.3225 0.9217 0.2155 +vn -0.7689 -0.3805 0.5138 +vn -0.4654 0.8286 0.3110 +vn -0.6929 -0.5528 0.4630 +vn -0.5905 0.7041 0.3945 +vn -0.5905 -0.7041 0.3945 +vn -0.6929 0.5528 0.4630 +vn -0.4654 -0.8286 0.3110 +vn -0.5172 0.8286 0.2142 +vn -0.8544 -0.3805 0.3539 +vn -0.7699 -0.5528 0.3189 +vn -0.6561 0.7041 0.2718 +vn -0.6561 -0.7041 0.2718 +vn -0.7699 0.5528 0.3189 +vn -0.5172 -0.8286 0.2142 +vn -0.8544 0.3805 0.3539 +vn -0.3584 -0.9217 0.1484 +vn -0.9063 0.1939 0.3754 +vn -0.1857 -0.9796 0.0769 +vn -0.9239 -0.0000 0.3827 +vn -0.1857 0.9796 0.0769 +vn -0.9063 -0.1939 0.3754 +vn -0.3584 0.9217 0.1484 +vn -0.9070 0.3805 0.1804 +vn -0.9622 0.1939 0.1914 +vn -0.1971 -0.9796 0.0392 +vn -0.9808 -0.0000 0.1951 +vn -0.1971 0.9796 0.0392 +vn -0.9622 -0.1939 0.1914 +vn -0.3804 0.9217 0.0757 +vn -0.9070 -0.3805 0.1804 +vn -0.5490 0.8286 0.1092 +vn -0.8173 -0.5528 0.1626 +vn -0.6965 0.7041 0.1385 +vn -0.6965 -0.7041 0.1385 +vn -0.8173 0.5528 0.1626 +vn -0.5490 -0.8286 0.1092 +vn -0.3804 -0.9217 0.0757 +vn -0.9248 -0.3805 -0.0000 +vn -0.8333 -0.5528 -0.0000 +vn -0.7101 0.7041 -0.0000 +vn -0.7101 -0.7041 -0.0000 +vn -0.8333 0.5528 -0.0000 +vn -0.5598 -0.8286 -0.0000 +vn -0.9248 0.3805 -0.0000 +vn -0.3879 -0.9217 -0.0000 +vn -0.9810 0.1939 -0.0000 +vn -0.2010 -0.9796 -0.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.2010 0.9796 -0.0000 +vn -0.9810 -0.1939 -0.0000 +vn -0.3879 0.9217 -0.0000 +vn -0.5598 0.8286 -0.0000 +vn -0.1971 -0.9796 -0.0392 +vn -0.9622 0.1939 -0.1914 +vn -0.9808 -0.0000 -0.1951 +vn -0.1971 0.9796 -0.0392 +vn -0.9622 -0.1939 -0.1914 +vn -0.3804 0.9217 -0.0757 +vn -0.9070 -0.3805 -0.1804 +vn -0.5490 0.8286 -0.1092 +vn -0.8173 -0.5528 -0.1626 +vn -0.6965 0.7041 -0.1385 +vn -0.6965 -0.7041 -0.1385 +vn -0.8173 0.5528 -0.1626 +vn -0.5490 -0.8286 -0.1092 +vn -0.9070 0.3805 -0.1804 +vn -0.3804 -0.9217 -0.0757 +vn -0.6561 -0.7041 -0.2718 +vn -0.6561 0.7041 -0.2718 +vn -0.7699 0.5528 -0.3189 +vn -0.5172 -0.8286 -0.2142 +vn -0.8544 0.3805 -0.3539 +vn -0.3584 -0.9217 -0.1484 +vn -0.9063 0.1939 -0.3754 +vn -0.1857 -0.9796 -0.0769 +vn -0.9239 -0.0000 -0.3827 +vn -0.1857 0.9796 -0.0769 +vn -0.9063 -0.1939 -0.3754 +vn -0.3584 0.9217 -0.1484 +vn -0.8544 -0.3805 -0.3539 +vn -0.5172 0.8286 -0.2142 +vn -0.7699 -0.5528 -0.3189 +vn -0.1671 0.9796 -0.1117 +vn -0.1671 -0.9796 -0.1117 +vn -0.8157 -0.1939 -0.5450 +vn -0.3225 0.9217 -0.2155 +vn -0.7689 -0.3805 -0.5138 +vn -0.4654 0.8286 -0.3110 +vn -0.6929 -0.5528 -0.4630 +vn -0.5905 0.7041 -0.3945 +vn -0.5905 -0.7041 -0.3945 +vn -0.6929 0.5528 -0.4630 +vn -0.4654 -0.8286 -0.3110 +vn -0.7689 0.3805 -0.5138 +vn -0.3225 -0.9217 -0.2155 +vn -0.8157 0.1939 -0.5450 +vn -0.8315 -0.0000 -0.5556 +vn -0.5021 0.7041 -0.5021 +vn -0.5893 0.5528 -0.5893 +vn -0.5021 -0.7041 -0.5021 +vn -0.3958 -0.8286 -0.3958 +vn -0.6539 0.3805 -0.6539 +vn -0.2743 -0.9217 -0.2743 +vn -0.6937 0.1939 -0.6937 +vn -0.1421 -0.9796 -0.1421 +vn -0.7071 -0.0000 -0.7071 +vn -0.1421 0.9796 -0.1421 +vn -0.6937 -0.1939 -0.6937 +vn -0.2743 0.9217 -0.2743 +vn -0.6539 -0.3805 -0.6539 +vn -0.3958 0.8286 -0.3958 +vn -0.5893 -0.5528 -0.5893 +vn -0.5450 -0.1939 -0.8157 +vn -0.2155 0.9217 -0.3225 +vn -0.5138 -0.3805 -0.7689 +vn -0.3110 0.8286 -0.4654 +vn -0.4630 -0.5528 -0.6929 +vn -0.3945 0.7041 -0.5905 +vn -0.3945 -0.7041 -0.5905 +vn -0.4630 0.5528 -0.6929 +vn -0.3110 -0.8286 -0.4654 +vn -0.5138 0.3805 -0.7689 +vn -0.2155 -0.9217 -0.3225 +vn -0.5450 0.1939 -0.8157 +vn -0.1117 -0.9796 -0.1671 +vn -0.5556 -0.0000 -0.8315 +vn -0.1117 0.9796 -0.1671 +vn -0.2718 -0.7041 -0.6561 +vn -0.2142 -0.8286 -0.5172 +vn -0.3539 0.3805 -0.8544 +vn -0.1484 -0.9217 -0.3584 +vn -0.3754 0.1939 -0.9063 +vn -0.0769 -0.9796 -0.1857 +vn -0.3827 -0.0000 -0.9239 +vn -0.0769 0.9796 -0.1857 +vn -0.3754 -0.1939 -0.9063 +vn -0.1484 0.9217 -0.3584 +vn -0.3539 -0.3805 -0.8544 +vn -0.2142 0.8286 -0.5172 +vn -0.3189 -0.5528 -0.7699 +vn -0.2718 0.7041 -0.6561 +vn -0.3189 0.5528 -0.7699 +vn -0.0757 0.9217 -0.3804 +vn -0.1804 -0.3805 -0.9070 +vn -0.1092 0.8286 -0.5490 +vn -0.1626 -0.5528 -0.8173 +vn -0.1385 0.7041 -0.6965 +vn -0.1385 -0.7041 -0.6965 +vn -0.1626 0.5528 -0.8173 +vn -0.1092 -0.8286 -0.5490 +vn -0.1804 0.3805 -0.9070 +vn -0.0757 -0.9217 -0.3804 +vn -0.1914 0.1939 -0.9622 +vn -0.0392 -0.9796 -0.1971 +vn -0.1951 -0.0000 -0.9808 +vn -0.0392 0.9796 -0.1971 +vn -0.1914 -0.1939 -0.9622 +vt 0.750000 0.812500 +vt 0.750000 0.687500 +vt 0.750000 0.562500 +vt 0.750000 0.500000 +vt 0.750000 0.437500 +vt 0.750000 0.312500 +vt 0.718750 0.937500 +vt 0.718750 0.875000 +vt 0.718750 0.812500 +vt 0.718750 0.750000 +vt 0.718750 0.687500 +vt 0.718750 0.625000 +vt 0.718750 0.562500 +vt 0.718750 0.500000 +vt 0.718750 0.437500 +vt 0.718750 0.375000 +vt 0.718750 0.312500 +vt 0.718750 0.250000 +vt 0.718750 0.187500 +vt 0.718750 0.125000 +vt 0.718750 0.062500 +vt 0.687500 0.937500 +vt 0.687500 0.875000 +vt 0.687500 0.812500 +vt 0.687500 0.750000 +vt 0.687500 0.687500 +vt 0.687500 0.625000 +vt 0.687500 0.562500 +vt 0.687500 0.500000 +vt 0.687500 0.437500 +vt 0.687500 0.375000 +vt 0.687500 0.312500 +vt 0.687500 0.250000 +vt 0.687500 0.187500 +vt 0.687500 0.125000 +vt 0.687500 0.062500 +vt 0.656250 0.937500 +vt 0.656250 0.875000 +vt 0.656250 0.812500 +vt 0.656250 0.750000 +vt 0.656250 0.687500 +vt 0.656250 0.625000 +vt 0.656250 0.562500 +vt 0.656250 0.500000 +vt 0.656250 0.437500 +vt 0.656250 0.375000 +vt 0.656250 0.312500 +vt 0.656250 0.250000 +vt 0.656250 0.187500 +vt 0.656250 0.125000 +vt 0.656250 0.062500 +vt 0.625000 0.937500 +vt 0.625000 0.875000 +vt 0.625000 0.812500 +vt 0.625000 0.750000 +vt 0.625000 0.687500 +vt 0.625000 0.625000 +vt 0.625000 0.562500 +vt 0.625000 0.500000 +vt 0.625000 0.437500 +vt 0.625000 0.375000 +vt 0.625000 0.312500 +vt 0.625000 0.250000 +vt 0.625000 0.187500 +vt 0.625000 0.125000 +vt 0.625000 0.062500 +vt 0.593750 0.937500 +vt 0.593750 0.875000 +vt 0.593750 0.812500 +vt 0.593750 0.750000 +vt 0.593750 0.687500 +vt 0.593750 0.625000 +vt 0.593750 0.562500 +vt 0.593750 0.500000 +vt 0.593750 0.437500 +vt 0.593750 0.375000 +vt 0.593750 0.312500 +vt 0.593750 0.250000 +vt 0.593750 0.187500 +vt 0.593750 0.125000 +vt 0.593750 0.062500 +vt 0.734375 1.000000 +vt 0.703125 1.000000 +vt 0.671875 1.000000 +vt 0.640625 1.000000 +vt 0.609375 1.000000 +vt 0.578125 1.000000 +vt 0.546875 1.000000 +vt 0.515625 1.000000 +vt 0.484375 1.000000 +vt 0.453125 1.000000 +vt 0.421875 1.000000 +vt 0.390625 1.000000 +vt 0.359375 1.000000 +vt 0.328125 1.000000 +vt 0.296875 1.000000 +vt 0.265625 1.000000 +vt 0.234375 1.000000 +vt 0.203125 1.000000 +vt 0.171875 1.000000 +vt 0.140625 1.000000 +vt 0.109375 1.000000 +vt 0.078125 1.000000 +vt 0.046875 1.000000 +vt 0.015625 1.000000 +vt 0.984375 1.000000 +vt 0.953125 1.000000 +vt 0.921875 1.000000 +vt 0.890625 1.000000 +vt 0.859375 1.000000 +vt 0.828125 1.000000 +vt 0.796875 1.000000 +vt 0.765625 1.000000 +vt 0.562500 0.937500 +vt 0.562500 0.875000 +vt 0.562500 0.812500 +vt 0.562500 0.750000 +vt 0.562500 0.687500 +vt 0.562500 0.625000 +vt 0.562500 0.562500 +vt 0.562500 0.500000 +vt 0.562500 0.437500 +vt 0.562500 0.375000 +vt 0.562500 0.312500 +vt 0.562500 0.250000 +vt 0.562500 0.187500 +vt 0.562500 0.125000 +vt 0.562500 0.062500 +vt 0.531250 0.937500 +vt 0.531250 0.875000 +vt 0.531250 0.812500 +vt 0.531250 0.750000 +vt 0.531250 0.687500 +vt 0.531250 0.625000 +vt 0.531250 0.562500 +vt 0.531250 0.500000 +vt 0.531250 0.437500 +vt 0.531250 0.375000 +vt 0.531250 0.312500 +vt 0.531250 0.250000 +vt 0.531250 0.187500 +vt 0.531250 0.125000 +vt 0.531250 0.062500 +vt 0.500000 0.937500 +vt 0.500000 0.875000 +vt 0.500000 0.812500 +vt 0.500000 0.750000 +vt 0.500000 0.687500 +vt 0.500000 0.625000 +vt 0.500000 0.562500 +vt 0.500000 0.500000 +vt 0.500000 0.437500 +vt 0.500000 0.375000 +vt 0.500000 0.312500 +vt 0.500000 0.250000 +vt 0.500000 0.187500 +vt 0.500000 0.125000 +vt 0.500000 0.062500 +vt 0.468750 0.937500 +vt 0.468750 0.875000 +vt 0.468750 0.812500 +vt 0.468750 0.750000 +vt 0.468750 0.687500 +vt 0.468750 0.625000 +vt 0.468750 0.562500 +vt 0.468750 0.500000 +vt 0.468750 0.437500 +vt 0.468750 0.375000 +vt 0.468750 0.312500 +vt 0.468750 0.250000 +vt 0.468750 0.187500 +vt 0.468750 0.125000 +vt 0.468750 0.062500 +vt 0.437500 0.937500 +vt 0.437500 0.875000 +vt 0.437500 0.812500 +vt 0.437500 0.750000 +vt 0.437500 0.687500 +vt 0.437500 0.625000 +vt 0.437500 0.562500 +vt 0.437500 0.500000 +vt 0.437500 0.437500 +vt 0.437500 0.375000 +vt 0.437500 0.312500 +vt 0.437500 0.250000 +vt 0.437500 0.187500 +vt 0.437500 0.125000 +vt 0.437500 0.062500 +vt 0.406250 0.937500 +vt 0.406250 0.875000 +vt 0.406250 0.812500 +vt 0.406250 0.750000 +vt 0.406250 0.687500 +vt 0.406250 0.625000 +vt 0.406250 0.562500 +vt 0.406250 0.500000 +vt 0.406250 0.437500 +vt 0.406250 0.375000 +vt 0.406250 0.312500 +vt 0.406250 0.250000 +vt 0.406250 0.187500 +vt 0.406250 0.125000 +vt 0.406250 0.062500 +vt 0.375000 0.937500 +vt 0.375000 0.875000 +vt 0.375000 0.812500 +vt 0.375000 0.750000 +vt 0.375000 0.687500 +vt 0.375000 0.625000 +vt 0.375000 0.562500 +vt 0.375000 0.500000 +vt 0.375000 0.437500 +vt 0.375000 0.375000 +vt 0.375000 0.312500 +vt 0.375000 0.250000 +vt 0.375000 0.187500 +vt 0.375000 0.125000 +vt 0.375000 0.062500 +vt 0.343750 0.937500 +vt 0.343750 0.875000 +vt 0.343750 0.812500 +vt 0.343750 0.750000 +vt 0.343750 0.687500 +vt 0.343750 0.625000 +vt 0.343750 0.562500 +vt 0.343750 0.500000 +vt 0.343750 0.437500 +vt 0.343750 0.375000 +vt 0.343750 0.312500 +vt 0.343750 0.250000 +vt 0.343750 0.187500 +vt 0.343750 0.125000 +vt 0.343750 0.062500 +vt 0.312500 0.937500 +vt 0.312500 0.875000 +vt 0.312500 0.812500 +vt 0.312500 0.750000 +vt 0.312500 0.687500 +vt 0.312500 0.625000 +vt 0.312500 0.562500 +vt 0.312500 0.500000 +vt 0.312500 0.437500 +vt 0.312500 0.375000 +vt 0.312500 0.312500 +vt 0.312500 0.250000 +vt 0.312500 0.187500 +vt 0.312500 0.125000 +vt 0.312500 0.062500 +vt 0.281250 0.937500 +vt 0.281250 0.875000 +vt 0.281250 0.812500 +vt 0.281250 0.750000 +vt 0.281250 0.687500 +vt 0.281250 0.625000 +vt 0.281250 0.562500 +vt 0.281250 0.500000 +vt 0.281250 0.437500 +vt 0.281250 0.375000 +vt 0.281250 0.312500 +vt 0.281250 0.250000 +vt 0.281250 0.187500 +vt 0.281250 0.125000 +vt 0.281250 0.062500 +vt 0.250000 0.937500 +vt 0.250000 0.875000 +vt 0.250000 0.812500 +vt 0.250000 0.750000 +vt 0.250000 0.687500 +vt 0.250000 0.625000 +vt 0.250000 0.562500 +vt 0.250000 0.500000 +vt 0.250000 0.437500 +vt 0.250000 0.375000 +vt 0.250000 0.312500 +vt 0.250000 0.250000 +vt 0.250000 0.187500 +vt 0.250000 0.125000 +vt 0.250000 0.062500 +vt 0.218750 0.937500 +vt 0.218750 0.875000 +vt 0.218750 0.812500 +vt 0.218750 0.750000 +vt 0.218750 0.687500 +vt 0.218750 0.625000 +vt 0.218750 0.562500 +vt 0.218750 0.500000 +vt 0.218750 0.437500 +vt 0.218750 0.375000 +vt 0.218750 0.312500 +vt 0.218750 0.250000 +vt 0.218750 0.187500 +vt 0.218750 0.125000 +vt 0.218750 0.062500 +vt 0.187500 0.937500 +vt 0.187500 0.875000 +vt 0.187500 0.812500 +vt 0.187500 0.750000 +vt 0.187500 0.687500 +vt 0.187500 0.625000 +vt 0.187500 0.562500 +vt 0.187500 0.500000 +vt 0.187500 0.437500 +vt 0.187500 0.375000 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.187500 0.187500 +vt 0.187500 0.125000 +vt 0.187500 0.062500 +vt 0.156250 0.937500 +vt 0.156250 0.875000 +vt 0.156250 0.812500 +vt 0.156250 0.750000 +vt 0.156250 0.687500 +vt 0.156250 0.625000 +vt 0.156250 0.562500 +vt 0.156250 0.500000 +vt 0.156250 0.437500 +vt 0.156250 0.375000 +vt 0.156250 0.312500 +vt 0.156250 0.250000 +vt 0.156250 0.187500 +vt 0.156250 0.125000 +vt 0.156250 0.062500 +vt 0.125000 0.937500 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.125000 0.750000 +vt 0.125000 0.687500 +vt 0.125000 0.625000 +vt 0.125000 0.562500 +vt 0.125000 0.500000 +vt 0.125000 0.437500 +vt 0.125000 0.375000 +vt 0.125000 0.312500 +vt 0.125000 0.250000 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.125000 0.062500 +vt 0.734375 0.000000 +vt 0.703125 0.000000 +vt 0.671875 0.000000 +vt 0.640625 0.000000 +vt 0.609375 0.000000 +vt 0.578125 0.000000 +vt 0.546875 0.000000 +vt 0.515625 0.000000 +vt 0.484375 0.000000 +vt 0.453125 0.000000 +vt 0.421875 0.000000 +vt 0.390625 0.000000 +vt 0.359375 0.000000 +vt 0.328125 0.000000 +vt 0.296875 0.000000 +vt 0.265625 0.000000 +vt 0.234375 0.000000 +vt 0.203125 0.000000 +vt 0.171875 0.000000 +vt 0.140625 0.000000 +vt 0.109375 0.000000 +vt 0.078125 0.000000 +vt 0.046875 0.000000 +vt 0.015625 0.000000 +vt 0.984375 0.000000 +vt 0.953125 0.000000 +vt 0.921875 0.000000 +vt 0.890625 0.000000 +vt 0.859375 0.000000 +vt 0.828125 0.000000 +vt 0.796875 0.000000 +vt 0.765625 0.000000 +vt 0.093750 0.937500 +vt 0.093750 0.875000 +vt 0.093750 0.812500 +vt 0.093750 0.750000 +vt 0.093750 0.687500 +vt 0.093750 0.625000 +vt 0.093750 0.562500 +vt 0.093750 0.500000 +vt 0.093750 0.437500 +vt 0.093750 0.375000 +vt 0.093750 0.312500 +vt 0.093750 0.250000 +vt 0.093750 0.187500 +vt 0.093750 0.125000 +vt 0.093750 0.062500 +vt 0.062500 0.937500 +vt 0.062500 0.875000 +vt 0.062500 0.812500 +vt 0.062500 0.750000 +vt 0.062500 0.687500 +vt 0.062500 0.625000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.062500 0.437500 +vt 0.062500 0.375000 +vt 0.062500 0.312500 +vt 0.062500 0.250000 +vt 0.062500 0.187500 +vt 0.062500 0.125000 +vt 0.062500 0.062500 +vt 0.031250 0.937500 +vt 0.031250 0.875000 +vt 0.031250 0.812500 +vt 0.031250 0.750000 +vt 0.031250 0.687500 +vt 0.031250 0.625000 +vt 0.031250 0.562500 +vt 0.031250 0.500000 +vt 0.031250 0.437500 +vt 0.031250 0.375000 +vt 0.031250 0.312500 +vt 0.031250 0.250000 +vt 0.031250 0.187500 +vt 0.031250 0.125000 +vt 0.031250 0.062500 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 0.000000 0.875000 +vt 1.000000 0.875000 +vt 0.000000 0.812500 +vt 1.000000 0.812500 +vt 0.000000 0.750000 +vt 1.000000 0.750000 +vt 0.000000 0.687500 +vt 1.000000 0.687500 +vt 0.000000 0.625000 +vt 1.000000 0.625000 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 0.000000 0.437500 +vt 1.000000 0.437500 +vt 0.000000 0.375000 +vt 1.000000 0.375000 +vt 0.000000 0.312500 +vt 1.000000 0.312500 +vt 0.000000 0.250000 +vt 1.000000 0.250000 +vt 0.000000 0.187500 +vt 1.000000 0.187500 +vt 0.000000 0.125000 +vt 1.000000 0.125000 +vt 1.000000 0.062500 +vt 0.000000 0.062500 +vt 0.968750 0.937500 +vt 0.968750 0.875000 +vt 0.968750 0.812500 +vt 0.968750 0.750000 +vt 0.968750 0.687500 +vt 0.968750 0.625000 +vt 0.968750 0.562500 +vt 0.968750 0.500000 +vt 0.968750 0.437500 +vt 0.968750 0.375000 +vt 0.968750 0.312500 +vt 0.968750 0.250000 +vt 0.968750 0.187500 +vt 0.968750 0.125000 +vt 0.968750 0.062500 +vt 0.937500 0.937500 +vt 0.937500 0.875000 +vt 0.937500 0.812500 +vt 0.937500 0.750000 +vt 0.937500 0.687500 +vt 0.937500 0.625000 +vt 0.937500 0.562500 +vt 0.937500 0.500000 +vt 0.937500 0.437500 +vt 0.937500 0.375000 +vt 0.937500 0.312500 +vt 0.937500 0.250000 +vt 0.937500 0.187500 +vt 0.937500 0.125000 +vt 0.937500 0.062500 +vt 0.906250 0.937500 +vt 0.906250 0.875000 +vt 0.906250 0.812500 +vt 0.906250 0.750000 +vt 0.906250 0.687500 +vt 0.906250 0.625000 +vt 0.906250 0.562500 +vt 0.906250 0.500000 +vt 0.906250 0.437500 +vt 0.906250 0.375000 +vt 0.906250 0.312500 +vt 0.906250 0.250000 +vt 0.906250 0.187500 +vt 0.906250 0.125000 +vt 0.906250 0.062500 +vt 0.875000 0.937500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.875000 0.750000 +vt 0.875000 0.687500 +vt 0.875000 0.625000 +vt 0.875000 0.562500 +vt 0.875000 0.500000 +vt 0.875000 0.437500 +vt 0.875000 0.375000 +vt 0.875000 0.312500 +vt 0.875000 0.250000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.875000 0.062500 +vt 0.843750 0.937500 +vt 0.843750 0.875000 +vt 0.843750 0.812500 +vt 0.843750 0.750000 +vt 0.843750 0.687500 +vt 0.843750 0.625000 +vt 0.843750 0.562500 +vt 0.843750 0.500000 +vt 0.843750 0.437500 +vt 0.843750 0.375000 +vt 0.843750 0.312500 +vt 0.843750 0.250000 +vt 0.843750 0.187500 +vt 0.843750 0.125000 +vt 0.843750 0.062500 +vt 0.812500 0.937500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.812500 0.750000 +vt 0.812500 0.687500 +vt 0.812500 0.625000 +vt 0.812500 0.562500 +vt 0.812500 0.500000 +vt 0.812500 0.437500 +vt 0.812500 0.375000 +vt 0.812500 0.312500 +vt 0.812500 0.250000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.812500 0.062500 +vt 0.781250 0.937500 +vt 0.781250 0.875000 +vt 0.781250 0.812500 +vt 0.781250 0.750000 +vt 0.781250 0.687500 +vt 0.781250 0.625000 +vt 0.781250 0.562500 +vt 0.781250 0.500000 +vt 0.781250 0.437500 +vt 0.781250 0.375000 +vt 0.781250 0.312500 +vt 0.781250 0.250000 +vt 0.781250 0.187500 +vt 0.781250 0.125000 +vt 0.781250 0.062500 +vt 0.750000 0.937500 +vt 0.750000 0.875000 +vt 0.750000 0.750000 +vt 0.750000 0.625000 +vt 0.750000 0.375000 +vt 0.750000 0.250000 +vt 0.750000 0.187500 +vt 0.750000 0.125000 +vt 0.750000 0.062500 +f 479/556/1 19/19/2 480/557/3 +f 477/554/4 11/11/5 12/12/6 +f 480/557/3 20/20/7 481/558/8 +f 3/3/9 12/12/6 13/13/10 +f 481/558/8 21/21/11 482/559/12 +f 3/3/9 14/14/13 4/4/14 +f 474/551/15 82/82/16 7/7/17 +f 308/339/18 482/559/12 21/21/11 +f 4/4/14 15/15/19 5/5/20 +f 475/552/21 7/7/17 8/8/22 +f 5/5/20 16/16/23 478/555/24 +f 1/1/25 8/8/22 9/9/26 +f 478/555/24 17/17/27 6/6/28 +f 476/553/29 9/9/26 10/10/30 +f 6/6/28 18/18/31 479/556/1 +f 2/2/32 10/10/30 11/11/5 +f 17/17/27 33/33/33 18/18/31 +f 10/10/30 26/26/34 11/11/5 +f 19/19/2 33/33/33 34/34/35 +f 11/11/5 27/27/36 12/12/6 +f 20/20/7 34/34/35 35/35/37 +f 13/13/10 27/27/36 28/28/38 +f 20/20/7 36/36/39 21/21/11 +f 13/13/10 29/29/40 14/14/13 +f 7/7/17 82/83/16 22/22/41 +f 308/340/18 21/21/11 36/36/39 +f 14/14/13 30/30/42 15/15/19 +f 7/7/17 23/23/43 8/8/22 +f 15/15/19 31/31/44 16/16/23 +f 8/8/22 24/24/45 9/9/26 +f 16/16/23 32/32/46 17/17/27 +f 9/9/26 25/25/47 10/10/30 +f 22/22/41 82/84/16 37/37/48 +f 308/341/18 36/36/39 51/51/49 +f 30/30/42 44/44/50 45/45/51 +f 22/22/41 38/38/52 23/23/43 +f 30/30/42 46/46/53 31/31/44 +f 23/23/43 39/39/54 24/24/45 +f 32/32/46 46/46/53 47/47/55 +f 24/24/45 40/40/56 25/25/47 +f 33/33/33 47/47/55 48/48/57 +f 25/25/47 41/41/58 26/26/34 +f 34/34/35 48/48/57 49/49/59 +f 26/26/34 42/42/60 27/27/36 +f 34/34/35 50/50/61 35/35/37 +f 27/27/36 43/43/62 28/28/38 +f 35/35/37 51/51/49 36/36/39 +f 28/28/38 44/44/50 29/29/40 +f 40/40/56 56/56/63 41/41/58 +f 48/48/57 64/64/64 49/49/59 +f 41/41/58 57/57/65 42/42/60 +f 49/49/59 65/65/66 50/50/61 +f 43/43/62 57/57/65 58/58/67 +f 50/50/61 66/66/68 51/51/49 +f 44/44/50 58/58/67 59/59/69 +f 37/37/48 82/85/16 52/52/70 +f 308/342/18 51/51/49 66/66/68 +f 44/44/50 60/60/71 45/45/51 +f 37/37/48 53/53/72 38/38/52 +f 45/45/51 61/61/73 46/46/53 +f 38/38/52 54/54/74 39/39/54 +f 47/47/55 61/61/73 62/62/75 +f 39/39/54 55/55/76 40/40/56 +f 47/47/55 63/63/77 48/48/57 +f 59/59/69 75/75/78 60/60/71 +f 52/52/70 68/68/79 53/53/72 +f 60/60/71 76/76/80 61/61/73 +f 53/53/72 69/69/81 54/54/74 +f 62/62/75 76/76/80 77/77/82 +f 54/54/74 70/70/83 55/55/76 +f 62/62/75 78/78/84 63/63/77 +f 56/56/63 70/70/83 71/71/85 +f 63/63/77 79/79/86 64/64/64 +f 56/56/63 72/72/87 57/57/65 +f 65/65/66 79/79/86 80/80/88 +f 58/58/67 72/72/87 73/73/89 +f 65/65/66 81/81/90 66/66/68 +f 59/59/69 73/73/89 74/74/91 +f 52/52/70 82/86/16 67/67/92 +f 308/343/18 66/66/68 81/81/90 +f 78/78/84 95/126/93 79/79/86 +f 71/71/85 88/119/94 72/72/87 +f 79/79/86 96/127/95 80/80/88 +f 73/73/89 88/119/94 89/120/96 +f 81/81/90 96/127/95 97/128/97 +f 74/74/91 89/120/96 90/121/98 +f 67/67/92 82/87/16 83/114/99 +f 308/344/18 81/81/90 97/128/97 +f 74/74/91 91/122/100 75/75/78 +f 67/67/92 84/115/101 68/68/79 +f 75/75/78 92/123/102 76/76/80 +f 68/68/79 85/116/103 69/69/81 +f 77/77/82 92/123/102 93/124/104 +f 69/69/81 86/117/105 70/70/83 +f 77/77/82 94/125/106 78/78/84 +f 71/71/85 86/117/105 87/118/107 +f 91/122/100 107/138/108 92/123/102 +f 84/115/101 100/131/109 85/116/103 +f 93/124/104 107/138/108 108/139/110 +f 85/116/103 101/132/111 86/117/105 +f 93/124/104 109/140/112 94/125/106 +f 87/118/107 101/132/111 102/133/113 +f 95/126/93 109/140/112 110/141/114 +f 87/118/107 103/134/115 88/119/94 +f 96/127/95 110/141/114 111/142/116 +f 89/120/96 103/134/115 104/135/117 +f 96/127/95 112/143/118 97/128/97 +f 90/121/98 104/135/117 105/136/119 +f 83/114/99 82/88/16 98/129/120 +f 308/345/18 97/128/97 112/143/118 +f 90/121/98 106/137/121 91/122/100 +f 84/115/101 98/129/120 99/130/122 +f 110/141/114 126/157/123 111/142/116 +f 104/135/117 118/149/124 119/150/125 +f 111/142/116 127/158/126 112/143/118 +f 105/136/119 119/150/125 120/151/127 +f 98/129/120 82/89/16 113/144/128 +f 308/346/18 112/143/118 127/158/126 +f 105/136/119 121/152/129 106/137/121 +f 99/130/122 113/144/128 114/145/130 +f 106/137/121 122/153/131 107/138/108 +f 99/130/122 115/146/132 100/131/109 +f 108/139/110 122/153/131 123/154/133 +f 100/131/109 116/147/134 101/132/111 +f 108/139/110 124/155/135 109/140/112 +f 102/133/113 116/147/134 117/148/136 +f 110/141/114 124/155/135 125/156/137 +f 102/133/113 118/149/124 103/134/115 +f 114/145/130 130/161/138 115/146/132 +f 123/154/133 137/168/139 138/169/140 +f 115/146/132 131/162/141 116/147/134 +f 123/154/133 139/170/142 124/155/135 +f 117/148/136 131/162/141 132/163/143 +f 125/156/137 139/170/142 140/171/144 +f 117/148/136 133/164/145 118/149/124 +f 125/156/137 141/172/146 126/157/123 +f 119/150/125 133/164/145 134/165/147 +f 126/157/123 142/173/148 127/158/126 +f 120/151/127 134/165/147 135/166/149 +f 113/144/128 82/90/16 128/159/150 +f 308/347/18 127/158/126 142/173/148 +f 120/151/127 136/167/151 121/152/129 +f 113/144/128 129/160/152 114/145/130 +f 121/152/129 137/168/139 122/153/131 +f 134/165/147 148/179/153 149/180/154 +f 142/173/148 156/187/155 157/188/156 +f 135/166/149 149/180/154 150/181/157 +f 128/159/150 82/91/16 143/174/158 +f 308/348/18 142/173/148 157/188/156 +f 135/166/149 151/182/159 136/167/151 +f 128/159/150 144/175/160 129/160/152 +f 136/167/151 152/183/161 137/168/139 +f 130/161/138 144/175/160 145/176/162 +f 138/169/140 152/183/161 153/184/163 +f 130/161/138 146/177/164 131/162/141 +f 138/169/140 154/185/165 139/170/142 +f 132/163/143 146/177/164 147/178/166 +f 140/171/144 154/185/165 155/186/167 +f 132/163/143 148/179/153 133/164/145 +f 140/171/144 156/187/155 141/172/146 +f 153/184/163 167/198/168 168/199/169 +f 145/176/162 161/192/170 146/177/164 +f 153/184/163 169/200/171 154/185/165 +f 147/178/166 161/192/170 162/193/172 +f 155/186/167 169/200/171 170/201/173 +f 147/178/166 163/194/174 148/179/153 +f 155/186/167 171/202/175 156/187/155 +f 149/180/154 163/194/174 164/195/176 +f 156/187/155 172/203/177 157/188/156 +f 150/181/157 164/195/176 165/196/178 +f 143/174/158 82/92/16 158/189/179 +f 308/349/18 157/188/156 172/203/177 +f 150/181/157 166/197/180 151/182/159 +f 143/174/158 159/190/181 144/175/160 +f 151/182/159 167/198/168 152/183/161 +f 145/176/162 159/190/181 160/191/182 +f 172/203/177 186/217/183 187/218/184 +f 165/196/178 179/210/185 180/211/186 +f 158/189/179 82/93/16 173/204/187 +f 308/350/18 172/203/177 187/218/184 +f 165/196/178 181/212/188 166/197/180 +f 158/189/179 174/205/189 159/190/181 +f 166/197/180 182/213/190 167/198/168 +f 159/190/181 175/206/191 160/191/182 +f 168/199/169 182/213/190 183/214/192 +f 160/191/182 176/207/193 161/192/170 +f 168/199/169 184/215/194 169/200/171 +f 162/193/172 176/207/193 177/208/195 +f 169/200/171 185/216/196 170/201/173 +f 162/193/172 178/209/197 163/194/174 +f 171/202/175 185/216/196 186/217/183 +f 164/195/176 178/209/197 179/210/185 +f 175/206/191 191/222/198 176/207/193 +f 183/214/192 199/230/199 184/215/194 +f 177/208/195 191/222/198 192/223/200 +f 185/216/196 199/230/199 200/231/201 +f 177/208/195 193/224/202 178/209/197 +f 185/216/196 201/232/203 186/217/183 +f 179/210/185 193/224/202 194/225/204 +f 186/217/183 202/233/205 187/218/184 +f 180/211/186 194/225/204 195/226/206 +f 173/204/187 82/94/16 188/219/207 +f 308/351/18 187/218/184 202/233/205 +f 180/211/186 196/227/208 181/212/188 +f 174/205/189 188/219/207 189/220/209 +f 181/212/188 197/228/210 182/213/190 +f 175/206/191 189/220/209 190/221/211 +f 183/214/192 197/228/210 198/229/212 +f 195/226/206 209/240/213 210/241/214 +f 188/219/207 82/95/16 203/234/215 +f 308/352/18 202/233/205 217/248/216 +f 195/226/206 211/242/217 196/227/208 +f 188/219/207 204/235/218 189/220/209 +f 196/227/208 212/243/219 197/228/210 +f 189/220/209 205/236/220 190/221/211 +f 198/229/212 212/243/219 213/244/221 +f 190/221/211 206/237/222 191/222/198 +f 198/229/212 214/245/223 199/230/199 +f 192/223/200 206/237/222 207/238/224 +f 200/231/201 214/245/223 215/246/225 +f 192/223/200 208/239/226 193/224/202 +f 200/231/201 216/247/227 201/232/203 +f 194/225/204 208/239/226 209/240/213 +f 201/232/203 217/248/216 202/233/205 +f 213/244/221 229/260/228 214/245/223 +f 207/238/224 221/252/229 222/253/230 +f 215/246/225 229/260/228 230/261/231 +f 207/238/224 223/254/232 208/239/226 +f 215/246/225 231/262/233 216/247/227 +f 209/240/213 223/254/232 224/255/234 +f 216/247/227 232/263/235 217/248/216 +f 210/241/214 224/255/234 225/256/236 +f 203/234/215 82/96/16 218/249/237 +f 308/353/18 217/248/216 232/263/235 +f 210/241/214 226/257/238 211/242/217 +f 203/234/215 219/250/239 204/235/218 +f 211/242/217 227/258/240 212/243/219 +f 204/235/218 220/251/241 205/236/220 +f 213/244/221 227/258/240 228/259/242 +f 205/236/220 221/252/229 206/237/222 +f 308/354/18 232/263/235 247/278/243 +f 225/256/236 241/272/244 226/257/238 +f 218/249/237 234/265/245 219/250/239 +f 226/257/238 242/273/246 227/258/240 +f 220/251/241 234/265/245 235/266/247 +f 228/259/242 242/273/246 243/274/248 +f 220/251/241 236/267/249 221/252/229 +f 228/259/242 244/275/250 229/260/228 +f 222/253/230 236/267/249 237/268/251 +f 230/261/231 244/275/250 245/276/252 +f 222/253/230 238/269/253 223/254/232 +f 230/261/231 246/277/254 231/262/233 +f 224/255/234 238/269/253 239/270/255 +f 232/263/235 246/277/254 247/278/243 +f 225/256/236 239/270/255 240/271/256 +f 218/249/237 82/97/16 233/264/257 +f 245/276/252 259/290/258 260/291/259 +f 237/268/251 253/284/260 238/269/253 +f 245/276/252 261/292/261 246/277/254 +f 239/270/255 253/284/260 254/285/262 +f 246/277/254 262/293/263 247/278/243 +f 240/271/256 254/285/262 255/286/264 +f 233/264/257 82/98/16 248/279/265 +f 308/355/18 247/278/243 262/293/263 +f 240/271/256 256/287/266 241/272/244 +f 233/264/257 249/280/267 234/265/245 +f 241/272/244 257/288/268 242/273/246 +f 234/265/245 250/281/269 235/266/247 +f 243/274/248 257/288/268 258/289/270 +f 235/266/247 251/282/271 236/267/249 +f 243/274/248 259/290/258 244/275/250 +f 237/268/251 251/282/271 252/283/272 +f 249/280/267 263/294/273 264/295/274 +f 256/287/266 272/303/275 257/288/268 +f 249/280/267 265/296/276 250/281/269 +f 258/289/270 272/303/275 273/304/277 +f 250/281/269 266/297/278 251/282/271 +f 258/289/270 274/305/279 259/290/258 +f 252/283/272 266/297/278 267/298/280 +f 260/291/259 274/305/279 275/306/281 +f 252/283/272 268/299/282 253/284/260 +f 260/291/259 276/307/283 261/292/261 +f 254/285/262 268/299/282 269/300/284 +f 261/292/261 277/308/285 262/293/263 +f 255/286/264 269/300/284 270/301/286 +f 248/279/265 82/99/16 263/294/273 +f 308/356/18 262/293/263 277/308/285 +f 255/286/264 271/302/287 256/287/266 +f 267/298/280 283/314/288 268/299/282 +f 275/306/281 291/322/289 276/307/283 +f 269/300/284 283/314/288 284/315/290 +f 277/308/285 291/322/289 292/323/291 +f 270/301/286 284/315/290 285/316/292 +f 263/294/273 82/100/16 278/309/293 +f 308/357/18 277/308/285 292/323/291 +f 270/301/286 286/317/294 271/302/287 +f 264/295/274 278/309/293 279/310/295 +f 271/302/287 287/318/296 272/303/275 +f 264/295/274 280/311/297 265/296/276 +f 273/304/277 287/318/296 288/319/298 +f 265/296/276 281/312/299 266/297/278 +f 273/304/277 289/320/300 274/305/279 +f 267/298/280 281/312/299 282/313/301 +f 275/306/281 289/320/300 290/321/302 +f 286/317/294 302/333/303 287/318/296 +f 279/310/295 295/326/304 280/311/297 +f 288/319/298 302/333/303 303/334/305 +f 280/311/297 296/327/306 281/312/299 +f 288/319/298 304/335/307 289/320/300 +f 282/313/301 296/327/306 297/328/308 +f 290/321/302 304/335/307 305/336/309 +f 282/313/301 298/329/310 283/314/288 +f 290/321/302 306/337/311 291/322/289 +f 284/315/290 298/329/310 299/330/312 +f 292/323/291 306/337/311 307/338/313 +f 285/316/292 299/330/312 300/331/314 +f 278/309/293 82/101/16 293/324/315 +f 308/358/18 292/323/291 307/338/313 +f 285/316/292 301/332/316 286/317/294 +f 278/309/293 294/325/317 279/310/295 +f 305/336/309 322/384/318 306/337/311 +f 299/330/312 314/376/319 315/377/320 +f 306/337/311 323/385/321 307/338/313 +f 300/331/314 315/377/320 316/378/322 +f 293/324/315 82/102/16 309/371/323 +f 308/359/18 307/338/313 323/385/321 +f 300/331/314 317/379/324 301/332/316 +f 293/324/315 310/372/325 294/325/317 +f 301/332/316 318/380/326 302/333/303 +f 294/325/317 311/373/327 295/326/304 +f 303/334/305 318/380/326 319/381/328 +f 295/326/304 312/374/329 296/327/306 +f 303/334/305 320/382/330 304/335/307 +f 297/328/308 312/374/329 313/375/331 +f 305/336/309 320/382/330 321/383/332 +f 297/328/308 314/376/319 298/329/310 +f 310/372/325 326/388/333 311/373/327 +f 319/381/328 333/395/334 334/396/335 +f 311/373/327 327/389/336 312/374/329 +f 319/381/328 335/397/337 320/382/330 +f 312/374/329 328/390/338 313/375/331 +f 321/383/332 335/397/337 336/398/339 +f 313/375/331 329/391/340 314/376/319 +f 321/383/332 337/399/341 322/384/318 +f 315/377/320 329/391/340 330/392/342 +f 322/384/318 338/400/343 323/385/321 +f 316/378/322 330/392/342 331/393/344 +f 309/371/323 82/103/16 324/386/345 +f 308/360/18 323/385/321 338/400/343 +f 316/378/322 332/394/346 317/379/324 +f 309/371/323 325/387/347 310/372/325 +f 317/379/324 333/395/334 318/380/326 +f 330/392/342 344/406/348 345/407/349 +f 337/399/341 353/415/350 338/400/343 +f 331/393/344 345/407/349 346/408/351 +f 324/386/345 82/104/16 339/401/352 +f 308/361/18 338/400/343 353/415/350 +f 331/393/344 347/409/353 332/394/346 +f 324/386/345 340/402/354 325/387/347 +f 332/394/346 348/410/355 333/395/334 +f 325/387/347 341/403/356 326/388/333 +f 334/396/335 348/410/355 349/411/357 +f 326/388/333 342/404/358 327/389/336 +f 334/396/335 350/412/359 335/397/337 +f 328/390/338 342/404/358 343/405/360 +f 336/398/339 350/412/359 351/413/361 +f 328/390/338 344/406/348 329/391/340 +f 336/398/339 352/414/362 337/399/341 +f 349/411/357 363/434/363 364/436/364 +f 341/403/356 357/422/365 342/404/358 +f 349/411/357 365/438/366 350/412/359 +f 343/405/360 357/422/365 358/424/367 +f 351/413/361 365/438/366 366/440/368 +f 343/405/360 359/426/369 344/406/348 +f 351/413/361 367/442/370 352/414/362 +f 345/407/349 359/426/369 360/428/371 +f 352/414/362 368/445/372 353/415/350 +f 346/408/351 360/428/371 361/430/373 +f 339/401/352 82/105/16 354/416/374 +f 308/362/18 353/415/350 368/445/372 +f 346/408/351 362/432/375 347/409/353 +f 339/401/352 355/418/376 340/402/354 +f 347/409/353 363/434/363 348/410/355 +f 341/403/356 355/418/376 356/420/377 +f 367/443/370 383/460/378 368/444/372 +f 361/431/373 375/452/379 376/453/380 +f 354/417/374 82/106/16 369/446/381 +f 308/363/18 368/444/372 383/460/378 +f 361/431/373 377/454/382 362/433/375 +f 354/417/374 370/447/383 355/419/376 +f 362/433/375 378/455/384 363/435/363 +f 356/421/377 370/447/383 371/448/385 +f 364/437/364 378/455/384 379/456/386 +f 356/421/377 372/449/387 357/423/365 +f 364/437/364 380/457/388 365/439/366 +f 358/425/367 372/449/387 373/450/389 +f 366/441/368 380/457/388 381/458/390 +f 358/425/367 374/451/391 359/427/369 +f 366/441/368 382/459/392 367/443/370 +f 360/429/371 374/451/391 375/452/379 +f 379/456/386 395/472/393 380/457/388 +f 373/450/389 387/464/394 388/465/395 +f 381/458/390 395/472/393 396/473/396 +f 373/450/389 389/466/397 374/451/391 +f 381/458/390 397/474/398 382/459/392 +f 375/452/379 389/466/397 390/467/399 +f 382/459/392 398/475/400 383/460/378 +f 376/453/380 390/467/399 391/468/401 +f 369/446/381 82/107/16 384/461/402 +f 308/364/18 383/460/378 398/475/400 +f 376/453/380 392/469/403 377/454/382 +f 369/446/381 385/462/404 370/447/383 +f 377/454/382 393/470/405 378/455/384 +f 371/448/385 385/462/404 386/463/406 +f 379/456/386 393/470/405 394/471/407 +f 371/448/385 387/464/394 372/449/387 +f 384/461/402 82/108/16 399/476/408 +f 308/365/18 398/475/400 413/490/409 +f 391/468/401 407/484/410 392/469/403 +f 385/462/404 399/476/408 400/477/411 +f 392/469/403 408/485/412 393/470/405 +f 385/462/404 401/478/413 386/463/406 +f 394/471/407 408/485/412 409/486/414 +f 386/463/406 402/479/415 387/464/394 +f 394/471/407 410/487/416 395/472/393 +f 388/465/395 402/479/415 403/480/417 +f 396/473/396 410/487/416 411/488/418 +f 388/465/395 404/481/419 389/466/397 +f 397/474/398 411/488/418 412/489/420 +f 390/467/399 404/481/419 405/482/421 +f 397/474/398 413/490/409 398/475/400 +f 391/468/401 405/482/421 406/483/422 +f 403/480/417 417/494/423 418/495/424 +f 411/488/418 425/502/425 426/503/426 +f 403/480/417 419/496/427 404/481/419 +f 411/488/418 427/504/428 412/489/420 +f 405/482/421 419/496/427 420/497/429 +f 412/489/420 428/505/430 413/490/409 +f 406/483/422 420/497/429 421/498/431 +f 399/476/408 82/109/16 414/491/432 +f 308/366/18 413/490/409 428/505/430 +f 406/483/422 422/499/433 407/484/410 +f 399/476/408 415/492/434 400/477/411 +f 407/484/410 423/500/435 408/485/412 +f 401/478/413 415/492/434 416/493/436 +f 409/486/414 423/500/435 424/501/437 +f 401/478/413 417/494/423 402/479/415 +f 409/486/414 425/502/425 410/487/416 +f 421/498/431 437/514/438 422/499/433 +f 414/491/432 430/507/439 415/492/434 +f 422/499/433 438/515/440 423/500/435 +f 416/493/436 430/507/439 431/508/441 +f 424/501/437 438/515/440 439/516/442 +f 416/493/436 432/509/443 417/494/423 +f 424/501/437 440/517/444 425/502/425 +f 418/495/424 432/509/443 433/510/445 +f 426/503/426 440/517/444 441/518/446 +f 418/495/424 434/511/447 419/496/427 +f 426/503/426 442/519/448 427/504/428 +f 420/497/429 434/511/447 435/512/449 +f 427/504/428 443/520/450 428/505/430 +f 421/498/431 435/512/449 436/513/451 +f 414/491/432 82/110/16 429/506/452 +f 308/367/18 428/505/430 443/520/450 +f 441/518/446 455/532/453 456/533/454 +f 433/510/445 449/526/455 434/511/447 +f 441/518/446 457/534/456 442/519/448 +f 435/512/449 449/526/455 450/527/457 +f 442/519/448 458/535/458 443/520/450 +f 436/513/451 450/527/457 451/528/459 +f 429/506/452 82/111/16 444/521/460 +f 308/368/18 443/520/450 458/535/458 +f 436/513/451 452/529/461 437/514/438 +f 430/507/439 444/521/460 445/522/462 +f 437/514/438 453/530/463 438/515/440 +f 430/507/439 446/523/464 431/508/441 +f 439/516/442 453/530/463 454/531/465 +f 431/508/441 447/524/466 432/509/443 +f 439/516/442 455/532/453 440/517/444 +f 433/510/445 447/524/466 448/525/467 +f 444/521/460 460/537/468 445/522/462 +f 452/529/461 468/545/469 453/530/463 +f 446/523/464 460/537/468 461/538/470 +f 454/531/465 468/545/469 469/546/471 +f 446/523/464 462/539/472 447/524/466 +f 454/531/465 470/547/473 455/532/453 +f 448/525/467 462/539/472 463/540/474 +f 456/533/454 470/547/473 471/548/475 +f 448/525/467 464/541/476 449/526/455 +f 456/533/454 472/549/477 457/534/456 +f 450/527/457 464/541/476 465/542/478 +f 458/535/458 472/549/477 473/550/479 +f 451/528/459 465/542/478 466/543/480 +f 444/521/460 82/112/16 459/536/481 +f 308/369/18 458/535/458 473/550/479 +f 451/528/459 467/544/482 452/529/461 +f 464/541/476 2/2/32 477/554/4 +f 471/548/475 481/558/8 472/549/477 +f 465/542/478 477/554/4 3/3/9 +f 472/549/477 482/559/12 473/550/479 +f 466/543/480 3/3/9 4/4/14 +f 459/536/481 82/113/16 474/551/15 +f 308/370/18 473/550/479 482/559/12 +f 466/543/480 5/5/20 467/544/482 +f 460/537/468 474/551/15 475/552/21 +f 467/544/482 478/555/24 468/545/469 +f 461/538/470 475/552/21 1/1/25 +f 468/545/469 6/6/28 469/546/471 +f 462/539/472 1/1/25 476/553/29 +f 469/546/471 479/556/1 470/547/473 +f 463/540/474 476/553/29 2/2/32 +f 471/548/475 479/556/1 480/557/3 +f 479/556/1 18/18/31 19/19/2 +f 477/554/4 2/2/32 11/11/5 +f 480/557/3 19/19/2 20/20/7 +f 3/3/9 477/554/4 12/12/6 +f 481/558/8 20/20/7 21/21/11 +f 3/3/9 13/13/10 14/14/13 +f 4/4/14 14/14/13 15/15/19 +f 475/552/21 474/551/15 7/7/17 +f 5/5/20 15/15/19 16/16/23 +f 1/1/25 475/552/21 8/8/22 +f 478/555/24 16/16/23 17/17/27 +f 476/553/29 1/1/25 9/9/26 +f 6/6/28 17/17/27 18/18/31 +f 2/2/32 476/553/29 10/10/30 +f 17/17/27 32/32/46 33/33/33 +f 10/10/30 25/25/47 26/26/34 +f 19/19/2 18/18/31 33/33/33 +f 11/11/5 26/26/34 27/27/36 +f 20/20/7 19/19/2 34/34/35 +f 13/13/10 12/12/6 27/27/36 +f 20/20/7 35/35/37 36/36/39 +f 13/13/10 28/28/38 29/29/40 +f 14/14/13 29/29/40 30/30/42 +f 7/7/17 22/22/41 23/23/43 +f 15/15/19 30/30/42 31/31/44 +f 8/8/22 23/23/43 24/24/45 +f 16/16/23 31/31/44 32/32/46 +f 9/9/26 24/24/45 25/25/47 +f 30/30/42 29/29/40 44/44/50 +f 22/22/41 37/37/48 38/38/52 +f 30/30/42 45/45/51 46/46/53 +f 23/23/43 38/38/52 39/39/54 +f 32/32/46 31/31/44 46/46/53 +f 24/24/45 39/39/54 40/40/56 +f 33/33/33 32/32/46 47/47/55 +f 25/25/47 40/40/56 41/41/58 +f 34/34/35 33/33/33 48/48/57 +f 26/26/34 41/41/58 42/42/60 +f 34/34/35 49/49/59 50/50/61 +f 27/27/36 42/42/60 43/43/62 +f 35/35/37 50/50/61 51/51/49 +f 28/28/38 43/43/62 44/44/50 +f 40/40/56 55/55/76 56/56/63 +f 48/48/57 63/63/77 64/64/64 +f 41/41/58 56/56/63 57/57/65 +f 49/49/59 64/64/64 65/65/66 +f 43/43/62 42/42/60 57/57/65 +f 50/50/61 65/65/66 66/66/68 +f 44/44/50 43/43/62 58/58/67 +f 44/44/50 59/59/69 60/60/71 +f 37/37/48 52/52/70 53/53/72 +f 45/45/51 60/60/71 61/61/73 +f 38/38/52 53/53/72 54/54/74 +f 47/47/55 46/46/53 61/61/73 +f 39/39/54 54/54/74 55/55/76 +f 47/47/55 62/62/75 63/63/77 +f 59/59/69 74/74/91 75/75/78 +f 52/52/70 67/67/92 68/68/79 +f 60/60/71 75/75/78 76/76/80 +f 53/53/72 68/68/79 69/69/81 +f 62/62/75 61/61/73 76/76/80 +f 54/54/74 69/69/81 70/70/83 +f 62/62/75 77/77/82 78/78/84 +f 56/56/63 55/55/76 70/70/83 +f 63/63/77 78/78/84 79/79/86 +f 56/56/63 71/71/85 72/72/87 +f 65/65/66 64/64/64 79/79/86 +f 58/58/67 57/57/65 72/72/87 +f 65/65/66 80/80/88 81/81/90 +f 59/59/69 58/58/67 73/73/89 +f 78/78/84 94/125/106 95/126/93 +f 71/71/85 87/118/107 88/119/94 +f 79/79/86 95/126/93 96/127/95 +f 73/73/89 72/72/87 88/119/94 +f 81/81/90 80/80/88 96/127/95 +f 74/74/91 73/73/89 89/120/96 +f 74/74/91 90/121/98 91/122/100 +f 67/67/92 83/114/99 84/115/101 +f 75/75/78 91/122/100 92/123/102 +f 68/68/79 84/115/101 85/116/103 +f 77/77/82 76/76/80 92/123/102 +f 69/69/81 85/116/103 86/117/105 +f 77/77/82 93/124/104 94/125/106 +f 71/71/85 70/70/83 86/117/105 +f 91/122/100 106/137/121 107/138/108 +f 84/115/101 99/130/122 100/131/109 +f 93/124/104 92/123/102 107/138/108 +f 85/116/103 100/131/109 101/132/111 +f 93/124/104 108/139/110 109/140/112 +f 87/118/107 86/117/105 101/132/111 +f 95/126/93 94/125/106 109/140/112 +f 87/118/107 102/133/113 103/134/115 +f 96/127/95 95/126/93 110/141/114 +f 89/120/96 88/119/94 103/134/115 +f 96/127/95 111/142/116 112/143/118 +f 90/121/98 89/120/96 104/135/117 +f 90/121/98 105/136/119 106/137/121 +f 84/115/101 83/114/99 98/129/120 +f 110/141/114 125/156/137 126/157/123 +f 104/135/117 103/134/115 118/149/124 +f 111/142/116 126/157/123 127/158/126 +f 105/136/119 104/135/117 119/150/125 +f 105/136/119 120/151/127 121/152/129 +f 99/130/122 98/129/120 113/144/128 +f 106/137/121 121/152/129 122/153/131 +f 99/130/122 114/145/130 115/146/132 +f 108/139/110 107/138/108 122/153/131 +f 100/131/109 115/146/132 116/147/134 +f 108/139/110 123/154/133 124/155/135 +f 102/133/113 101/132/111 116/147/134 +f 110/141/114 109/140/112 124/155/135 +f 102/133/113 117/148/136 118/149/124 +f 114/145/130 129/160/152 130/161/138 +f 123/154/133 122/153/131 137/168/139 +f 115/146/132 130/161/138 131/162/141 +f 123/154/133 138/169/140 139/170/142 +f 117/148/136 116/147/134 131/162/141 +f 125/156/137 124/155/135 139/170/142 +f 117/148/136 132/163/143 133/164/145 +f 125/156/137 140/171/144 141/172/146 +f 119/150/125 118/149/124 133/164/145 +f 126/157/123 141/172/146 142/173/148 +f 120/151/127 119/150/125 134/165/147 +f 120/151/127 135/166/149 136/167/151 +f 113/144/128 128/159/150 129/160/152 +f 121/152/129 136/167/151 137/168/139 +f 134/165/147 133/164/145 148/179/153 +f 142/173/148 141/172/146 156/187/155 +f 135/166/149 134/165/147 149/180/154 +f 135/166/149 150/181/157 151/182/159 +f 128/159/150 143/174/158 144/175/160 +f 136/167/151 151/182/159 152/183/161 +f 130/161/138 129/160/152 144/175/160 +f 138/169/140 137/168/139 152/183/161 +f 130/161/138 145/176/162 146/177/164 +f 138/169/140 153/184/163 154/185/165 +f 132/163/143 131/162/141 146/177/164 +f 140/171/144 139/170/142 154/185/165 +f 132/163/143 147/178/166 148/179/153 +f 140/171/144 155/186/167 156/187/155 +f 153/184/163 152/183/161 167/198/168 +f 145/176/162 160/191/182 161/192/170 +f 153/184/163 168/199/169 169/200/171 +f 147/178/166 146/177/164 161/192/170 +f 155/186/167 154/185/165 169/200/171 +f 147/178/166 162/193/172 163/194/174 +f 155/186/167 170/201/173 171/202/175 +f 149/180/154 148/179/153 163/194/174 +f 156/187/155 171/202/175 172/203/177 +f 150/181/157 149/180/154 164/195/176 +f 150/181/157 165/196/178 166/197/180 +f 143/174/158 158/189/179 159/190/181 +f 151/182/159 166/197/180 167/198/168 +f 145/176/162 144/175/160 159/190/181 +f 172/203/177 171/202/175 186/217/183 +f 165/196/178 164/195/176 179/210/185 +f 165/196/178 180/211/186 181/212/188 +f 158/189/179 173/204/187 174/205/189 +f 166/197/180 181/212/188 182/213/190 +f 159/190/181 174/205/189 175/206/191 +f 168/199/169 167/198/168 182/213/190 +f 160/191/182 175/206/191 176/207/193 +f 168/199/169 183/214/192 184/215/194 +f 162/193/172 161/192/170 176/207/193 +f 169/200/171 184/215/194 185/216/196 +f 162/193/172 177/208/195 178/209/197 +f 171/202/175 170/201/173 185/216/196 +f 164/195/176 163/194/174 178/209/197 +f 175/206/191 190/221/211 191/222/198 +f 183/214/192 198/229/212 199/230/199 +f 177/208/195 176/207/193 191/222/198 +f 185/216/196 184/215/194 199/230/199 +f 177/208/195 192/223/200 193/224/202 +f 185/216/196 200/231/201 201/232/203 +f 179/210/185 178/209/197 193/224/202 +f 186/217/183 201/232/203 202/233/205 +f 180/211/186 179/210/185 194/225/204 +f 180/211/186 195/226/206 196/227/208 +f 174/205/189 173/204/187 188/219/207 +f 181/212/188 196/227/208 197/228/210 +f 175/206/191 174/205/189 189/220/209 +f 183/214/192 182/213/190 197/228/210 +f 195/226/206 194/225/204 209/240/213 +f 195/226/206 210/241/214 211/242/217 +f 188/219/207 203/234/215 204/235/218 +f 196/227/208 211/242/217 212/243/219 +f 189/220/209 204/235/218 205/236/220 +f 198/229/212 197/228/210 212/243/219 +f 190/221/211 205/236/220 206/237/222 +f 198/229/212 213/244/221 214/245/223 +f 192/223/200 191/222/198 206/237/222 +f 200/231/201 199/230/199 214/245/223 +f 192/223/200 207/238/224 208/239/226 +f 200/231/201 215/246/225 216/247/227 +f 194/225/204 193/224/202 208/239/226 +f 201/232/203 216/247/227 217/248/216 +f 213/244/221 228/259/242 229/260/228 +f 207/238/224 206/237/222 221/252/229 +f 215/246/225 214/245/223 229/260/228 +f 207/238/224 222/253/230 223/254/232 +f 215/246/225 230/261/231 231/262/233 +f 209/240/213 208/239/226 223/254/232 +f 216/247/227 231/262/233 232/263/235 +f 210/241/214 209/240/213 224/255/234 +f 210/241/214 225/256/236 226/257/238 +f 203/234/215 218/249/237 219/250/239 +f 211/242/217 226/257/238 227/258/240 +f 204/235/218 219/250/239 220/251/241 +f 213/244/221 212/243/219 227/258/240 +f 205/236/220 220/251/241 221/252/229 +f 225/256/236 240/271/256 241/272/244 +f 218/249/237 233/264/257 234/265/245 +f 226/257/238 241/272/244 242/273/246 +f 220/251/241 219/250/239 234/265/245 +f 228/259/242 227/258/240 242/273/246 +f 220/251/241 235/266/247 236/267/249 +f 228/259/242 243/274/248 244/275/250 +f 222/253/230 221/252/229 236/267/249 +f 230/261/231 229/260/228 244/275/250 +f 222/253/230 237/268/251 238/269/253 +f 230/261/231 245/276/252 246/277/254 +f 224/255/234 223/254/232 238/269/253 +f 232/263/235 231/262/233 246/277/254 +f 225/256/236 224/255/234 239/270/255 +f 245/276/252 244/275/250 259/290/258 +f 237/268/251 252/283/272 253/284/260 +f 245/276/252 260/291/259 261/292/261 +f 239/270/255 238/269/253 253/284/260 +f 246/277/254 261/292/261 262/293/263 +f 240/271/256 239/270/255 254/285/262 +f 240/271/256 255/286/264 256/287/266 +f 233/264/257 248/279/265 249/280/267 +f 241/272/244 256/287/266 257/288/268 +f 234/265/245 249/280/267 250/281/269 +f 243/274/248 242/273/246 257/288/268 +f 235/266/247 250/281/269 251/282/271 +f 243/274/248 258/289/270 259/290/258 +f 237/268/251 236/267/249 251/282/271 +f 249/280/267 248/279/265 263/294/273 +f 256/287/266 271/302/287 272/303/275 +f 249/280/267 264/295/274 265/296/276 +f 258/289/270 257/288/268 272/303/275 +f 250/281/269 265/296/276 266/297/278 +f 258/289/270 273/304/277 274/305/279 +f 252/283/272 251/282/271 266/297/278 +f 260/291/259 259/290/258 274/305/279 +f 252/283/272 267/298/280 268/299/282 +f 260/291/259 275/306/281 276/307/283 +f 254/285/262 253/284/260 268/299/282 +f 261/292/261 276/307/283 277/308/285 +f 255/286/264 254/285/262 269/300/284 +f 255/286/264 270/301/286 271/302/287 +f 267/298/280 282/313/301 283/314/288 +f 275/306/281 290/321/302 291/322/289 +f 269/300/284 268/299/282 283/314/288 +f 277/308/285 276/307/283 291/322/289 +f 270/301/286 269/300/284 284/315/290 +f 270/301/286 285/316/292 286/317/294 +f 264/295/274 263/294/273 278/309/293 +f 271/302/287 286/317/294 287/318/296 +f 264/295/274 279/310/295 280/311/297 +f 273/304/277 272/303/275 287/318/296 +f 265/296/276 280/311/297 281/312/299 +f 273/304/277 288/319/298 289/320/300 +f 267/298/280 266/297/278 281/312/299 +f 275/306/281 274/305/279 289/320/300 +f 286/317/294 301/332/316 302/333/303 +f 279/310/295 294/325/317 295/326/304 +f 288/319/298 287/318/296 302/333/303 +f 280/311/297 295/326/304 296/327/306 +f 288/319/298 303/334/305 304/335/307 +f 282/313/301 281/312/299 296/327/306 +f 290/321/302 289/320/300 304/335/307 +f 282/313/301 297/328/308 298/329/310 +f 290/321/302 305/336/309 306/337/311 +f 284/315/290 283/314/288 298/329/310 +f 292/323/291 291/322/289 306/337/311 +f 285/316/292 284/315/290 299/330/312 +f 285/316/292 300/331/314 301/332/316 +f 278/309/293 293/324/315 294/325/317 +f 305/336/309 321/383/332 322/384/318 +f 299/330/312 298/329/310 314/376/319 +f 306/337/311 322/384/318 323/385/321 +f 300/331/314 299/330/312 315/377/320 +f 300/331/314 316/378/322 317/379/324 +f 293/324/315 309/371/323 310/372/325 +f 301/332/316 317/379/324 318/380/326 +f 294/325/317 310/372/325 311/373/327 +f 303/334/305 302/333/303 318/380/326 +f 295/326/304 311/373/327 312/374/329 +f 303/334/305 319/381/328 320/382/330 +f 297/328/308 296/327/306 312/374/329 +f 305/336/309 304/335/307 320/382/330 +f 297/328/308 313/375/331 314/376/319 +f 310/372/325 325/387/347 326/388/333 +f 319/381/328 318/380/326 333/395/334 +f 311/373/327 326/388/333 327/389/336 +f 319/381/328 334/396/335 335/397/337 +f 312/374/329 327/389/336 328/390/338 +f 321/383/332 320/382/330 335/397/337 +f 313/375/331 328/390/338 329/391/340 +f 321/383/332 336/398/339 337/399/341 +f 315/377/320 314/376/319 329/391/340 +f 322/384/318 337/399/341 338/400/343 +f 316/378/322 315/377/320 330/392/342 +f 316/378/322 331/393/344 332/394/346 +f 309/371/323 324/386/345 325/387/347 +f 317/379/324 332/394/346 333/395/334 +f 330/392/342 329/391/340 344/406/348 +f 337/399/341 352/414/362 353/415/350 +f 331/393/344 330/392/342 345/407/349 +f 331/393/344 346/408/351 347/409/353 +f 324/386/345 339/401/352 340/402/354 +f 332/394/346 347/409/353 348/410/355 +f 325/387/347 340/402/354 341/403/356 +f 334/396/335 333/395/334 348/410/355 +f 326/388/333 341/403/356 342/404/358 +f 334/396/335 349/411/357 350/412/359 +f 328/390/338 327/389/336 342/404/358 +f 336/398/339 335/397/337 350/412/359 +f 328/390/338 343/405/360 344/406/348 +f 336/398/339 351/413/361 352/414/362 +f 349/411/357 348/410/355 363/434/363 +f 341/403/356 356/420/377 357/422/365 +f 349/411/357 364/436/364 365/438/366 +f 343/405/360 342/404/358 357/422/365 +f 351/413/361 350/412/359 365/438/366 +f 343/405/360 358/424/367 359/426/369 +f 351/413/361 366/440/368 367/442/370 +f 345/407/349 344/406/348 359/426/369 +f 352/414/362 367/442/370 368/445/372 +f 346/408/351 345/407/349 360/428/371 +f 346/408/351 361/430/373 362/432/375 +f 339/401/352 354/416/374 355/418/376 +f 347/409/353 362/432/375 363/434/363 +f 341/403/356 340/402/354 355/418/376 +f 367/443/370 382/459/392 383/460/378 +f 361/431/373 360/429/371 375/452/379 +f 361/431/373 376/453/380 377/454/382 +f 354/417/374 369/446/381 370/447/383 +f 362/433/375 377/454/382 378/455/384 +f 356/421/377 355/419/376 370/447/383 +f 364/437/364 363/435/363 378/455/384 +f 356/421/377 371/448/385 372/449/387 +f 364/437/364 379/456/386 380/457/388 +f 358/425/367 357/423/365 372/449/387 +f 366/441/368 365/439/366 380/457/388 +f 358/425/367 373/450/389 374/451/391 +f 366/441/368 381/458/390 382/459/392 +f 360/429/371 359/427/369 374/451/391 +f 379/456/386 394/471/407 395/472/393 +f 373/450/389 372/449/387 387/464/394 +f 381/458/390 380/457/388 395/472/393 +f 373/450/389 388/465/395 389/466/397 +f 381/458/390 396/473/396 397/474/398 +f 375/452/379 374/451/391 389/466/397 +f 382/459/392 397/474/398 398/475/400 +f 376/453/380 375/452/379 390/467/399 +f 376/453/380 391/468/401 392/469/403 +f 369/446/381 384/461/402 385/462/404 +f 377/454/382 392/469/403 393/470/405 +f 371/448/385 370/447/383 385/462/404 +f 379/456/386 378/455/384 393/470/405 +f 371/448/385 386/463/406 387/464/394 +f 391/468/401 406/483/422 407/484/410 +f 385/462/404 384/461/402 399/476/408 +f 392/469/403 407/484/410 408/485/412 +f 385/462/404 400/477/411 401/478/413 +f 394/471/407 393/470/405 408/485/412 +f 386/463/406 401/478/413 402/479/415 +f 394/471/407 409/486/414 410/487/416 +f 388/465/395 387/464/394 402/479/415 +f 396/473/396 395/472/393 410/487/416 +f 388/465/395 403/480/417 404/481/419 +f 397/474/398 396/473/396 411/488/418 +f 390/467/399 389/466/397 404/481/419 +f 397/474/398 412/489/420 413/490/409 +f 391/468/401 390/467/399 405/482/421 +f 403/480/417 402/479/415 417/494/423 +f 411/488/418 410/487/416 425/502/425 +f 403/480/417 418/495/424 419/496/427 +f 411/488/418 426/503/426 427/504/428 +f 405/482/421 404/481/419 419/496/427 +f 412/489/420 427/504/428 428/505/430 +f 406/483/422 405/482/421 420/497/429 +f 406/483/422 421/498/431 422/499/433 +f 399/476/408 414/491/432 415/492/434 +f 407/484/410 422/499/433 423/500/435 +f 401/478/413 400/477/411 415/492/434 +f 409/486/414 408/485/412 423/500/435 +f 401/478/413 416/493/436 417/494/423 +f 409/486/414 424/501/437 425/502/425 +f 421/498/431 436/513/451 437/514/438 +f 414/491/432 429/506/452 430/507/439 +f 422/499/433 437/514/438 438/515/440 +f 416/493/436 415/492/434 430/507/439 +f 424/501/437 423/500/435 438/515/440 +f 416/493/436 431/508/441 432/509/443 +f 424/501/437 439/516/442 440/517/444 +f 418/495/424 417/494/423 432/509/443 +f 426/503/426 425/502/425 440/517/444 +f 418/495/424 433/510/445 434/511/447 +f 426/503/426 441/518/446 442/519/448 +f 420/497/429 419/496/427 434/511/447 +f 427/504/428 442/519/448 443/520/450 +f 421/498/431 420/497/429 435/512/449 +f 441/518/446 440/517/444 455/532/453 +f 433/510/445 448/525/467 449/526/455 +f 441/518/446 456/533/454 457/534/456 +f 435/512/449 434/511/447 449/526/455 +f 442/519/448 457/534/456 458/535/458 +f 436/513/451 435/512/449 450/527/457 +f 436/513/451 451/528/459 452/529/461 +f 430/507/439 429/506/452 444/521/460 +f 437/514/438 452/529/461 453/530/463 +f 430/507/439 445/522/462 446/523/464 +f 439/516/442 438/515/440 453/530/463 +f 431/508/441 446/523/464 447/524/466 +f 439/516/442 454/531/465 455/532/453 +f 433/510/445 432/509/443 447/524/466 +f 444/521/460 459/536/481 460/537/468 +f 452/529/461 467/544/482 468/545/469 +f 446/523/464 445/522/462 460/537/468 +f 454/531/465 453/530/463 468/545/469 +f 446/523/464 461/538/470 462/539/472 +f 454/531/465 469/546/471 470/547/473 +f 448/525/467 447/524/466 462/539/472 +f 456/533/454 455/532/453 470/547/473 +f 448/525/467 463/540/474 464/541/476 +f 456/533/454 471/548/475 472/549/477 +f 450/527/457 449/526/455 464/541/476 +f 458/535/458 457/534/456 472/549/477 +f 451/528/459 450/527/457 465/542/478 +f 451/528/459 466/543/480 467/544/482 +f 464/541/476 463/540/474 2/2/32 +f 471/548/475 480/557/3 481/558/8 +f 465/542/478 464/541/476 477/554/4 +f 472/549/477 481/558/8 482/559/12 +f 466/543/480 465/542/478 3/3/9 +f 466/543/480 4/4/14 5/5/20 +f 460/537/468 459/536/481 474/551/15 +f 467/544/482 5/5/20 478/555/24 +f 461/538/470 460/537/468 475/552/21 +f 468/545/469 478/555/24 6/6/28 +f 462/539/472 461/538/470 1/1/25 +f 469/546/471 6/6/28 479/556/1 +f 463/540/474 462/539/472 476/553/29 +f 471/548/475 470/547/473 479/556/1 diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index f435938..ba195d4 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -76,21 +76,34 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.src_field = TaichiSource.field() self.brdf_field = BRDF.field() self.bsdf_field = BSDF.field() - self.textures = Texture.field() + + # These four texture mappings might be accessed with the same pattern + self.albedo_map = Texture.field() + self.normal_map = Texture.field() + self.bump_map = Texture.field() + self.roughness_map = Texture.field() # TODO: this is useless for now + ti.root.dense(ti.i, self.src_num).place(self.src_field) # Light source Taichi storage self.brdf_nodes = ti.root.bitmasked(ti.i, self.num_objects) self.brdf_nodes.place(self.brdf_field) # BRDF Taichi storage ti.root.bitmasked(ti.i, self.num_objects).place(self.bsdf_field) # BRDF Taichi storage (no node needed) - ti.root.bitmasked(ti.i, self.num_objects).place(self.textures) + ti.root.bitmasked(ti.i, self.num_objects).place(self.albedo_map, self.normal_map, self.bump_map, self.roughness_map) - if prop["packed_texture"] is None: - self.texture_img = ti.Vector.field(3, float, (1, 1)) + if prop["packed_textures"] is None: + self.albedo_img = ti.Vector.field(3, float, (1, 1)) + self.normal_img = ti.Vector.field(3, float, (1, 1)) + self.bump_img = ti.Vector.field(3, float, (1, 1)) + self.roughness_img = ti.Vector.field(3, float, (1, 1)) else: - image = prop["packed_texture"] - tex_h, tex_w, _ = image.shape - self.texture_img = ti.Vector.field(3, float, (tex_w, tex_h)) - self.texture_img.from_numpy(image) - CONSOLE.log(f"Packed texture images loaded: ({tex_w}, {tex_h})") + images = prop["packed_texture"] # dict ('albedo': Optional(), 'normal': ...) + for key, image in images.item(): + if image is None: # no image means we don't have this kind of mapping + self.__setattr__(f"{key}_img", ti.Vector.field(3, float, (1, 1))) + continue + tex_h, tex_w, _ = image.shape + self.__setattr__(f"{key}_img", ti.Vector.field(3, float, (tex_w, tex_h))) + self.__getattribute__(f"{key}_img").from_numpy(image) + CONSOLE.log(f"Packed texture image tagged '{key}' loaded: ({tex_w}, {tex_h})") CONSOLE.log(f"Path tracer param loading in {self.clock.toc_tic(True):.3f} ms") self.initialze(emitters, objects) @@ -179,6 +192,7 @@ def prepare_for_bvh(self, objects: List[ObjDescriptor]): return primitives, obj_info def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): + # FIXME: Path tracer initialization is too slow self.uv_coords.fill(0) for i, emitter in enumerate(emitters): self.src_field[i] = emitter.export() @@ -214,10 +228,11 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): self.bsdf_field[i] = obj.bsdf.export() else: self.brdf_field[i] = obj.bsdf.export() - if obj.texture is None: - self.textures[i] = Texture_np.default() - else: - self.textures[i] = obj.texture.export() + + for key, value in obj.texture_group.items(): # exporting texture group + if value is not None: + self.__getattribute__(f"{key}_map")[i] = value.export() + self.aabbs[i, 0] = vec3(obj.aabb[0]) # unrolled self.aabbs[i, 1] = vec3(obj.aabb[1]) emitter_ref_id = obj.emitter_ref_id @@ -229,8 +244,7 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): def get_uv_item(self, textures: ti.template(), tex_img: ti.template(), obj_id: int, prim_id: int, u: float, v: float): """ Convert primitive local UV to the global UV coord for an object """ color = INVALID - has_texture = textures[obj_id].type > -255 - if has_texture: + if ti.is_active(textures, obj_id): is_sphere = self.obj_info[obj_id, 2] if is_sphere == 0: # not a sphere u, v = self.uv_coords[prim_id, 1] * u + self.uv_coords[prim_id, 2] * v + \ @@ -270,9 +284,6 @@ def bvh_intersect(self, bvh_id, ray, start_p): @ti.func def ray_intersect_bvh(self, ray: vec3, start_p, min_depth = -1.0): - # FIXME: major revision should be made. In order to properly use texture - # We need to return the intersection barycentric coordinates / sphere coordinates - # This is going to be a laborious job """ Ray intersection with BVH, to prune unnecessary computation """ obj_id = -1 prim_id = -1 @@ -345,7 +356,6 @@ def does_intersect_bvh(self, ray, start_p, min_depth = -1.0): node_idx += 1 return hit_flag - # TODO: some profiling is needed, passing by reference or by value, which one is faster? @ti.func def sample_new_ray(self, idx: int, incid: vec3, normal: vec3, is_mi: int, From ba2f7259e7d8a6d1bb82f4a59a9ebb684bc43f49 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Sun, 18 Jun 2023 00:54:56 +0800 Subject: [PATCH 03/18] WIP: lerp v normal during rendering. --- parsers/obj_loader.py | 2 +- parsers/texture_packing.py | 4 ++-- parsers/xml_parser.py | 18 ++++++++++++------ tracer/path_tracer.py | 29 ++++++++++++++++++++++++----- tracer/tracer_base.py | 2 ++ 5 files changed, 41 insertions(+), 14 deletions(-) diff --git a/parsers/obj_loader.py b/parsers/obj_loader.py index 7236db7..29d63d0 100644 --- a/parsers/obj_loader.py +++ b/parsers/obj_loader.py @@ -43,7 +43,7 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): dim_num = sum([int(part[1:]) for part in all_parts]) all_data = np.float32(material.vertices).reshape(-1, dim_num) mesh_faces = None - vert_normal = None + vert_normal = None # note that vert_normal is of the same shape with mesh_faces (N, 3, 3) uv_coords = None for part in all_parts: if part.startswith("T"): diff --git a/parsers/texture_packing.py b/parsers/texture_packing.py index 802e8ff..439477a 100644 --- a/parsers/texture_packing.py +++ b/parsers/texture_packing.py @@ -41,9 +41,9 @@ def image_packer(textures: List[Texture_np]) -> Tuple[np.ndarray, List[Texture_n if max_size > 1024: starting_point = 0 elif max_size > 720: - starting_point = 1 + starting_point = min(starting_point, 1) elif max_size > 400: - starting_point = 2 + starting_point = min(starting_point, 2) total_size += h * w rects.append((w, h, idx)) # but rect_id does total_size = np.sqrt(total_size) * 1.1 # 1.1 is for redundancy diff --git a/parsers/xml_parser.py b/parsers/xml_parser.py index e4c1491..12bde42 100644 --- a/parsers/xml_parser.py +++ b/parsers/xml_parser.py @@ -87,7 +87,9 @@ def parse_wavefront( # Some emitters will be attached to objects, to sample the object-attached emitters # We need to calculate surface area of the object mesh first (asuming each triangle has similar area) attached_area_dict = {} + has_vertex_normal = False for elem in obj_list: + # vns: vertex normals / uvs: uv coordinates vns, uvs, trans_r, trans_t = None, None, None, None # uv_coordinates and transform obj_type = 0 if elem.get("type") == "obj": @@ -98,6 +100,8 @@ def parse_wavefront( if transform_child is not None: trans_r, trans_t = transform_parse(transform_child) meshes, normals = apply_transform(meshes, normals, trans_r, trans_t) + if vns is not None: + has_vertex_normal = True else: # CURRENTLY, only sphere is supported meshes, normals = parse_sphere_element(elem) obj_type = 1 @@ -132,7 +136,7 @@ def parse_wavefront( if bsdf_item is None: raise ValueError("Object should be attached with a BSDF for now since no default one implemented yet.") all_objs.append(ObjDescriptor(meshes, normals, bsdf_item, vns, uvs, texture_group, trans_r, trans_t, emit_ref_id, obj_type)) - return all_objs, attached_area_dict + return all_objs, attached_area_dict, has_vertex_normal def parse_bxdf(bxdf_list: List[xet.Element]): """ @@ -224,19 +228,21 @@ def scene_parsing(directory: str, file: str): bsdf_dict = parse_bxdf(bxdf_nodes) teximgs, textures = parse_texture(texture_nodes) """ Texture mapping should be updateded (FIXME): - (1) . Now for each object, there can only be one ref for each type of reference + - [x] . Now for each object, there can only be one ref for each type of reference But TODO: texture needs more that one (albedo map, normal map, bump map, roughness map), for other mappings I do not want to implement them. Therefore, 1-to-many mapping should be correctly established - (2) Loading from python to Taichi (for different kinds of mapping) + - [x] Loading from python to Taichi (for different kinds of mapping) Each mapping might needs a different packing, therefore we need different image packaging and texture info block For normal mapping, non-bidirectional renderers will be simple but not for BDPT roughness is of lower priority - (3) Speed up python->taichi conversion + - [ ] Speed up python->taichi conversion """ - meshes, area_lut = parse_wavefront(directory, shape_nodes, bsdf_dict, emitter_dict, textures) + meshes, area_lut, has_vertex_normal \ + = parse_wavefront(directory, shape_nodes, bsdf_dict, emitter_dict, textures) configs = parse_global_sensor(sensor_node) configs['world'] = parse_world(world_node) - configs['packed_textures'] = teximgs + configs['packed_textures'] = teximgs + configs['has_vertex_normal'] = has_vertex_normal emitter_configs = update_emitter_config(emitter_configs, area_lut) return emitter_configs, meshes, configs diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index ba195d4..7ae1c9a 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -22,7 +22,7 @@ from bxdf.brdf import BRDF from bxdf.bsdf import BSDF, BSDF_np -from bxdf.texture import Texture, Texture_np +from bxdf.texture import Texture from parsers.opts import get_options from parsers.obj_desc import ObjDescriptor from parsers.xml_parser import scene_parsing @@ -72,6 +72,7 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.emitter_id = ti.field(int, self.num_objects) self.src_num = len(emitters) + self.v_normals = ti.Vector.field(3, float) self.color = ti.Vector.field(3, float, (self.w, self.h)) # color without normalization self.src_field = TaichiSource.field() self.brdf_field = BRDF.field() @@ -81,6 +82,9 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.albedo_map = Texture.field() self.normal_map = Texture.field() self.bump_map = Texture.field() + + # FIXME: I might need to dive deeper, this might not be appropriate + # maybe we should opt for environment map (env lighting) self.roughness_map = Texture.field() # TODO: this is useless for now ti.root.dense(ti.i, self.src_num).place(self.src_field) # Light source Taichi storage @@ -104,6 +108,13 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.__setattr__(f"{key}_img", ti.Vector.field(3, float, (tex_w, tex_h))) self.__getattribute__(f"{key}_img").from_numpy(image) CONSOLE.log(f"Packed texture image tagged '{key}' loaded: ({tex_w}, {tex_h})") + + self.has_v_normal = prop["has_vertex_normal"] + if prop["has_vertex_normal"]: + CONSOLE.log(f"Vertex normals found. Allocating storage for v-normals.") + self.prim_handle.place(self.v_normals) # actual vertex normal storage + else: + ti.root.bitmasked(ti.i, 1).place(self.v_normals) # A dummy place CONSOLE.log(f"Path tracer param loading in {self.clock.toc_tic(True):.3f} ms") self.initialze(emitters, objects) @@ -200,7 +211,8 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): acc_prim_num = 0 for i, obj in enumerate(objects): - for j, (mesh, normal) in tqdm.tqdm(enumerate(zip(obj.meshes, obj.normals))): + prim_num = obj.meshes.shape[0] + for j, (mesh, normal) in tqdm.tqdm(enumerate(zip(obj.meshes, obj.normals)), total = prim_num): cur_id = acc_prim_num + j self.prims[cur_id, 0] = vec3(mesh[0]) self.prims[cur_id, 1] = vec3(mesh[1]) @@ -212,13 +224,20 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): else: self.precom_vec[cur_id, 0] = self.prims[cur_id, 0] self.precom_vec[cur_id, 1] = self.prims[cur_id, 1] + if obj.vns is not None: # got vertex normal + pass self.normals[cur_id] = vec3(normal) - if obj.uv_coords is not None: - for j, uv_coord in tqdm.tqdm(enumerate(obj.uv_coords)): - cur_id = acc_prim_num + j + if obj.uv_coords is not None: + uv_coord = obj.uv_coords[j] self.uv_coords[cur_id, 0] = vec2(uv_coord[0]) self.uv_coords[cur_id, 1] = vec2(uv_coord[1]) self.uv_coords[cur_id, 2] = vec2(uv_coord[2]) + if obj.vns is not None: + vn = obj.vns[j] + self.v_normals[cur_id, 0] = vec2(vn[0]) + self.v_normals[cur_id, 1] = vec2(vn[1]) + self.v_normals[cur_id, 2] = vec2(vn[2]) + self.obj_info[i, 0] = acc_prim_num self.obj_info[i, 1] = obj.tri_num self.obj_info[i, 2] = obj.type diff --git a/tracer/tracer_base.py b/tracer/tracer_base.py index 8e1ce44..3a8b17d 100644 --- a/tracer/tracer_base.py +++ b/tracer/tracer_base.py @@ -71,6 +71,8 @@ def __init__(self, objects: List[ObjDescriptor], prop: dict): # A more compact way to store the primitives self.aabbs = ti.Vector.field(3, float, (self.num_objects, 2)) + + # geometric normal for surfaces self.normals = ti.Vector.field(3, float) self.prims = ti.Vector.field(3, float) # leveraging SSDS, shape (N, mesh_num, 3) - vector3d self.uv_coords = ti.Vector.field(2, float) # uv coordinates From 5e0828d6f4a18d16311ab5952b3123b54ec28688 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Mon, 19 Jun 2023 00:45:02 +0800 Subject: [PATCH 04/18] WIP: major refactoring work with interaction --- bxdf/brdf.py | 36 ++++++++++++++++-------------- renderer/path_utils.py | 38 ++++++++++++++++++------------- renderer/vanilla_renderer.py | 14 +++++++----- tracer/interaction.py | 40 +++++++++++++++++++++++++++++++++ tracer/path_tracer.py | 43 +++++++++++++++++++----------------- tracer/tracer_base.py | 18 ++++++++++----- 6 files changed, 125 insertions(+), 64 deletions(-) create mode 100644 tracer/interaction.py diff --git a/bxdf/brdf.py b/bxdf/brdf.py index 08dc30f..e760c03 100644 --- a/bxdf/brdf.py +++ b/bxdf/brdf.py @@ -109,7 +109,7 @@ class BRDF: # ======================= Blinn-Phong ======================== @ti.func - def eval_blinn_phong(self, ray_in: vec3, ray_out: vec3, normal: vec3, tex = INVALID): + def eval_blinn_phong(self, it:ti.template(), ray_in: vec3, ray_out: vec3): """ Normally, ray in is along the opposite direction of normal Attention: ray_in (in backward tracing) is actually out-going direction (in forward tracing) @@ -120,18 +120,18 @@ def eval_blinn_phong(self, ray_in: vec3, ray_out: vec3, normal: vec3, tex = INVA half_way = half_way.normalized() else: half_way.fill(0.0) - dot_clamp = ti.max(0.0, tm.dot(half_way, normal)) + dot_clamp = ti.max(0.0, tm.dot(half_way, it.n_s)) glossy = tm.pow(dot_clamp, self.k_g) - cosine_term = ti.max(0.0, tm.dot(normal, ray_out)) + cosine_term = ti.max(0.0, tm.dot(it.n_s, ray_out)) # A modified Phong model (k_d + k_s should be smaller than 1, otherwise not physically plausible) - diffuse_color = ti.select(tex[0] < 0, self.k_d, tex) + diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, it.tex) return (diffuse_color + self.k_s * (0.5 * (self.k_g + 2.0) * glossy)) * INV_PI * cosine_term @ti.func - def sample_blinn_phong(self, incid: vec3, normal: vec3, tex = INVALID): + def sample_blinn_phong(self, it:ti.template(), incid: vec3): local_new_dir, pdf = cosine_hemisphere() - ray_out_d, _ = delocalize_rotate(normal, local_new_dir) - spec = self.eval_blinn_phong(incid, ray_out_d, normal, tex) + ray_out_d, _ = delocalize_rotate(it.n_s, local_new_dir) + spec = self.eval_blinn_phong(it, incid, ray_out_d) return ray_out_d, spec, pdf # ====================== Modified Phong ======================= @@ -229,16 +229,16 @@ def sample_fresnel_blend(self, incid: vec3, normal: vec3, tex = INVALID): # ======================= Lambertian ======================== @ti.func - def eval_lambertian(self, ray_out: vec3, normal: vec3, tex = INVALID): - cosine_term = tm.max(0.0, tm.dot(normal, ray_out)) - diffuse_color = ti.select(tex[0] < 0, self.k_d, tex) + def eval_lambertian(self, it: ti.template(), ray_out: vec3): + cosine_term = tm.max(0.0, tm.dot(ti.n_s, ray_out)) + diffuse_color = ti.select(tex[0] < 0, self.k_d, ti.tex) return diffuse_color * INV_PI * cosine_term @ti.func - def sample_lambertian(self, normal: vec3, tex = INVALID): + def sample_lambertian(self, it: ti.template()): local_new_dir, pdf = cosine_hemisphere() - ray_out_d, _ = delocalize_rotate(normal, local_new_dir) - spec = self.eval_lambertian(ray_out_d, normal, tex) + ray_out_d, _ = delocalize_rotate(it.n_s, local_new_dir) + spec = self.eval_lambertian(ray_out_d, it., tex) return ray_out_d, spec, pdf # ======================= Mirror-Specular ======================== @@ -250,13 +250,13 @@ def sample_specular(self, ray_in: vec3, normal: vec3, tex = INVALID): # ================================================================ @ti.func - def eval(self, incid: vec3, out: vec3, normal: vec3, tex = INVALID) -> vec3: + def eval(self, it: ti.template(), incid: vec3, out: vec3) -> vec3: """ Direct component reflectance Every evaluation function does not output cosine weighted BSDF now """ ret_spec = vec3([0, 0, 0]) # For reflection, incident (in reverse direction) & outdir should be in the same hemisphere defined by the normal - if tm.dot(incid, normal) * tm.dot(out, normal) < 0: + if tm.dot(incid, it.n_g) * tm.dot(out, it.n_g) < 0: if self._type == 0: # Blinn-Phong ret_spec = self.eval_blinn_phong(incid, out, normal, tex) elif self._type == 1: # Lambertian @@ -269,7 +269,7 @@ def eval(self, incid: vec3, out: vec3, normal: vec3, tex = INVALID) -> vec3: return ret_spec @ti.func - def sample_new_rays(self, incid: vec3, normal: vec3, tex = INVALID): + def sample_new_rays(self, it:ti.template(), incid: vec3): """ All the sampling function will return: (1) new ray (direction) \\ (2) rendering equation transfer term (BRDF * cos term) (3) PDF @@ -281,7 +281,7 @@ def sample_new_rays(self, incid: vec3, normal: vec3, tex = INVALID): ret_spec = vec3([1, 1, 1]) pdf = 1.0 if self._type == 0: # Blinn-Phong - ret_dir, ret_spec, pdf = self.sample_blinn_phong(incid, normal, tex) + ret_dir, ret_spec, pdf = self.sample_blinn_phong(it, incid) elif self._type == 1: # Lambertian ret_dir, ret_spec, pdf = self.sample_lambertian(normal, tex) elif self._type == 2: # Specular - specular has no cosine attenuation @@ -292,6 +292,8 @@ def sample_new_rays(self, incid: vec3, normal: vec3, tex = INVALID): ret_dir, ret_spec, pdf = self.sample_fresnel_blend(incid, normal, tex) else: print(f"Warnning: unknown or unsupported BRDF type: {self._type} during sampling.") + ret_dot = tm.dot(ret_dir, it.n_g) + ret_spec = ti.select(ret_dot > 0, ret_spec, 0.) return ret_dir, ret_spec, pdf @ti.func diff --git a/renderer/path_utils.py b/renderer/path_utils.py index 51a358e..b6a7cd6 100644 --- a/renderer/path_utils.py +++ b/renderer/path_utils.py @@ -18,22 +18,30 @@ class Vertex: """ A (64 + 12)-Byte Path Vertex """ - _type: ti.i8 # 0 for surface, 1 for medium, 2 for light, 3 for camera - obj_id: ti.i8 # hit object (BSDF) id - emit_id: ti.i8 # if the vertex is on a area emitter, just store the emitter info - - # Bool bits: [0 pos delta, 1 dir delta, 2 is area, 3 is inifite, 4 is in free space, 5 is specular delta, others reserved] + _type: ti.i8 + """ 0 for surface, 1 for medium, 2 for light, 3 for camera """ + obj_id: ti.i8 + """ hit object (BSDF) id """ + emit_id: ti.i8 + """ if the vertex is on a area emitter, just store the emitter info """ bool_bits: ti.i8 - - pdf_fwd: float # forward pdf - pdf_bwd: float # backward pdf - time: float # hit time (reserved for future uses) - - normal: vec3 # hit normal - pos: vec3 # hit pos - ray_in: vec3 # incident ray direction (towards pos) - beta: vec3 # path throughput - tex: vec3 # texture color (used to calculate color during BDPT connection) + """ Bool bits: [0 pos delta, 1 dir delta, 2 is area, 3 is inifite, 4 is in free space, 5 is specular delta, others reserved] """ + pdf_fwd: float + """ forward pdf """ + pdf_bwd: float + """ backward pdf """ + time: float + """ hit time (reserved for future uses) """ + normal: vec3 + """ hit normal """ + pos: vec3 + """ hit pos """ + ray_in: vec3 + """ incident ray direction (towards pos) """ + beta: vec3 + """ path throughput """ + tex: vec3 + """ texture color (used to calculate color during BDPT connection) """ @ti.func def set_pdf_bwd(self, pdf: float, next_point: vec3): diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index f92cae4..2e8ab05 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -9,6 +9,7 @@ from typing import List from la.cam_transform import * from tracer.path_tracer import PathTracer +from tracer.interaction import Interaction from emitters.abtract_source import LightSource from parsers.obj_desc import ObjDescriptor @@ -33,13 +34,14 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int if not self.do_crop or in_crop_range: ray_d = self.pix2ray(i, j) ray_o = self.cam_t - obj_id, normal, min_depth, prim_id, u_coord, v_coord = self.ray_intersect(ray_d, ray_o) - hit_light = self.emitter_id[ti.max(obj_id, 0)] # id for hit emitter, if nothing is hit, this value will be -1 + it = self.ray_intersect(ray_d, ray_o) + # obj_id, normal, min_depth, prim_id, u_coord, v_coord + hit_light = self.emitter_id[ti.max(it.obj_id, 0)] # id for hit emitter, if nothing is hit, this value will be -1 color = vec3([0, 0, 0]) contribution = vec3([1, 1, 1]) emission_weight = 1.0 for _i in range(self.max_bounce): - if obj_id < 0: break # nothing is hit, break + if it.is_ray_not_hit() < 0: break # nothing is hit, break if ti.static(self.use_rr): # Simple Russian Roullete ray termination max_value = contribution.max() @@ -47,7 +49,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int else: contribution *= 1. / (max_value + 1e-7) # unbiased calculation else: if contribution.max() < 1e-4: break # contribution too small, break - hit_point = ray_d * min_depth + ray_o + hit_point = ray_d * it.min_depth + ray_o direct_pdf = 1.0 emitter_pdf = 1.0 @@ -55,7 +57,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) + it.tex = self.get_uv_item(self.albedo_map, self.albedo_img, it) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) @@ -97,7 +99,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int color += (direct_int + emit_int * emission_weight) * contribution # VERY IMPORTANT: rendering should be done according to rendering equation (approximation) contribution *= indirect_spec / ray_pdf - obj_id, normal, min_depth, prim_id, u_coord, v_coord = self.ray_intersect(ray_d, ray_o) + it = self.ray_intersect(ray_d, ray_o) if obj_id >= 0: hit_light = self.emitter_id[obj_id] diff --git a/tracer/interaction.py b/tracer/interaction.py new file mode 100644 index 0000000..d309e6a --- /dev/null +++ b/tracer/interaction.py @@ -0,0 +1,40 @@ +""" + We really need a interaction class to manage + the ever-increasing complexity introduced by ray intersection + @author Qianyue He + @date 2023.6.18 +""" + +import taichi as ti +from taichi.math import vec2, vec3 + +@ti.dataclass +class Interaction: + """ Surface interaction management class """ + + obj_id: int + """ index for object intersected """ + prim_id: int + """ primitive for object intersected """ + n_s: vec3 + """ shading normal """ + n_g: vec3 + """ geometric normal """ + tex: vec3 + """ Texture color. Maybe we need more fields like roughness, etc. """ + uv: vec2 + """ uv_coordinates. When returing from ray_intersect, this is local uv + Local uv should be post-processed to be global uv + """ + min_depth: float + """ minimum depth to a surface """ + + # obj_id, normal, min_depth, u_coord, v_coord + + @ti.func + def is_ray_not_hit(self): + return self.obj_id < 0 + + @ti.func + def is_tex_invalid(self): + return self.tex[0] < 0 \ No newline at end of file diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 7ae1c9a..7974f5d 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -30,6 +30,7 @@ from sampler.general_sampling import * from utils.tools import TicToc +from tracer.interaction import Interaction from tracer.ti_bvh import LinearBVH, LinearNode, export_python_bvh from rich.console import Console @@ -260,16 +261,15 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): self.src_field[emitter_ref_id].obj_ref_id = i @ti.func - def get_uv_item(self, textures: ti.template(), tex_img: ti.template(), obj_id: int, prim_id: int, u: float, v: float): + def get_uv_item(self, textures: ti.template(), tex_img: ti.template(), it: ti.template()): """ Convert primitive local UV to the global UV coord for an object """ - color = INVALID - if ti.is_active(textures, obj_id): - is_sphere = self.obj_info[obj_id, 2] + it.tex = INVALID + if ti.is_active(textures, it.obj_id): + is_sphere = self.obj_info[it.obj_id, 2] if is_sphere == 0: # not a sphere - u, v = self.uv_coords[prim_id, 1] * u + self.uv_coords[prim_id, 2] * v + \ - self.uv_coords[prim_id, 0] * (1. - u - v) - color = textures[obj_id].query(tex_img, u, v) - return color + u, v = self.uv_coords[it.prim_id, 1] * u + self.uv_coords[it.prim_id, 2] * v + \ + self.uv_coords[it.prim_id, 0] * (1. - u - v) + it.tex = textures[it.obj_id].query(tex_img, u, v) @ti.func def bvh_intersect(self, bvh_id, ray, start_p): @@ -335,17 +335,20 @@ def ray_intersect_bvh(self, ray: vec3, start_p, min_depth = -1.0): coord_u = u coord_v = v node_idx += 1 - normal = vec3([1, 0, 0]) + n_g = vec3([1, 0, 0]) if obj_id >= 0: if sphere_flag: center = self.prims[prim_id, 0] - normal = (start_p + min_depth * ray - center).normalized() - coord_u = (tm.atan2(normal[1], normal[0]) + tm.pi) * INV_2PI - coord_v = tm.acos(normal[2]) * INV_PI + n_g = (start_p + min_depth * ray - center).normalized() + coord_u = (tm.atan2(n_g[1], n_g[0]) + tm.pi) * INV_2PI + coord_v = tm.acos(n_g[2]) * INV_PI else: - normal = self.normals[prim_id] + n_g = self.normals[prim_id] # The returned coord_u and coord_v is not the actual uv coords (but for one specific primitive) - return (obj_id, normal, min_depth, prim_id, coord_u, coord_v) + return Interaction( + obj_id = obj_id, prim_id = prim_id, n_g = n_g, n_s = n_g, + uv = vec2(coord_u, coord_v), min_depth = min_depth + ) @ti.func def does_intersect_bvh(self, ray, start_p, min_depth = -1.0): @@ -406,24 +409,24 @@ def sample_new_ray(self, return ret_dir, ret_spec, ret_pdf @ti.func - def eval(self, idx: int, incid: vec3, out: vec3, normal: vec3, - is_mi: int, in_free_space: int, mode: int = TRANSPORT_UNI, tex: vec3 = INVALID) -> vec3: + def eval(self, it: ti.template(), incid: vec3, out: vec3, is_mi: int, + in_free_space: int, mode: int = TRANSPORT_UNI) -> vec3: ret_spec = vec3([1, 1, 1]) if is_mi: # FIXME: eval_phase and phase function currently return a float if in_free_space: # evaluate world medium ret_spec.fill(self.world.medium.eval(incid, out)) else: # is_mi implys is_scattering = True - ret_spec.fill(self.bsdf_field[idx].medium.eval(incid, out)) + ret_spec.fill(self.bsdf_field[it.obj_id].medium.eval(incid, out)) else: # surface interaction - if ti.is_active(self.brdf_nodes, idx): # active means the object is attached to BRDF + if ti.is_active(self.brdf_nodes, it.obj_id): # active means the object is attached to BRDF if ti.static(self.brdf_two_sides): dot_res = tm.dot(incid, normal) if dot_res > 0.: # two sides normal *= -1 - ret_spec = self.brdf_field[idx].eval(incid, out, normal, tex) + ret_spec = self.brdf_field[it.obj_id].eval(incid, out, normal, tex) else: # directly evaluate surface - ret_spec = self.bsdf_field[idx].eval_surf(incid, out, normal, self.world.medium, mode, tex) + ret_spec = self.bsdf_field[it.obj_id].eval_surf(incid, out, normal, self.world.medium, mode, tex) return ret_spec @ti.func diff --git a/tracer/tracer_base.py b/tracer/tracer_base.py index 3a8b17d..b585f79 100644 --- a/tracer/tracer_base.py +++ b/tracer/tracer_base.py @@ -17,6 +17,7 @@ from la.cam_transform import * from parsers.obj_desc import ObjDescriptor +from tracer.interaction import Interaction from parsers.xml_parser import scene_parsing from renderer.constants import INV_PI, INV_2PI @@ -85,6 +86,7 @@ def __init__(self, objects: List[ObjDescriptor], prop: dict): self.prim_handle = self.dense_nodes.dense(ti.j, 3) self.prim_handle.place(self.prims, self.precom_vec) # for simple shapes, this would be efficient self.prim_handle.place(self.uv_coords) + self.has_v_normal = False # pos0: start_idx, pos1: number of primitives, pos2: obj_id (being triangle / sphere? Others to be added, like cylinder, etc.) self.obj_info = ti.field(int, (self.num_objects, 3)) @@ -182,16 +184,20 @@ def ray_intersect(self, ray, start_p, min_depth = -1.0): coord_u = u coord_v = v sphere_flag = False - normal = vec3([1, 0, 0]) + n_g = vec3([1, 0, 0]) if obj_id >= 0: if sphere_flag: center = self.prims[prm_id, 0] - normal = (start_p + min_depth * ray - center).normalized() - coord_u = (tm.atan2(normal[1], normal[0]) + tm.pi) * INV_2PI - coord_v = tm.acos(normal[2]) * INV_PI + n_g = (start_p + min_depth * ray - center).normalized() + coord_u = (tm.atan2(n_g[1], n_g[0]) + tm.pi) * INV_2PI + coord_v = tm.acos(n_g[2]) * INV_PI else: - normal = self.normals[prm_id] - return (obj_id, normal, min_depth, prm_id, coord_u, coord_v) + n_g = self.normals[prm_id] + # We should calculate global uv and n_s outside + return Interaction( + obj_id = obj_id, prim_id = prm_id, n_g = n_g, n_s = n_g, + uv = vec2(coord_u, coord_v), min_depth = min_depth + ) @ti.func def does_intersect(self, ray, start_p, min_depth = -1.0): From 58a167d1f3de2f71f877440e8339c949d8927b47 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Tue, 20 Jun 2023 00:39:38 +0800 Subject: [PATCH 05/18] WIP: vnorm is more difficult than expected. --- bxdf/brdf.py | 86 ++++++++++++++++++------------------ bxdf/bsdf.py | 40 +++++++++-------- emitters/abtract_source.py | 6 +-- renderer/path_utils.py | 12 ++++- renderer/vanilla_renderer.py | 16 +++---- tracer/path_tracer.py | 35 ++++----------- 6 files changed, 94 insertions(+), 101 deletions(-) diff --git a/bxdf/brdf.py b/bxdf/brdf.py index e760c03..8b84547 100644 --- a/bxdf/brdf.py +++ b/bxdf/brdf.py @@ -136,32 +136,31 @@ def sample_blinn_phong(self, it:ti.template(), incid: vec3): # ====================== Modified Phong ======================= @ti.func - def eval_mod_phong(self, ray_in: vec3, ray_out: vec3, normal: vec3): - dot_normal = tm.dot(normal, ray_out) + def eval_mod_phong(self, it: ti.template(), ray_in: vec3, ray_out: vec3): + dot_normal = tm.dot(it.n_s, ray_out) spec = vec3([0, 0, 0]) if dot_normal > 0.0: # Phong model - specular part - reflect_d = (2 * normal * dot_normal - ray_out).normalized() + reflect_d = (2 * it.n_s * dot_normal - ray_out).normalized() dot_view = ti.max(0.0, -tm.dot(ray_in, reflect_d)) # ray_in is on the opposite dir of reflected dir glossy = tm.pow(dot_view, self.k_g) * self.k_s spec = 0.5 * (self.k_g + 2.) * glossy * INV_PI * dot_normal return spec @ti.func - def sample_mod_phong(self, incid: vec3, normal: vec3, tex = INVALID): + def sample_mod_phong(self, it: ti.template(), incid: vec3): # Sampling is more complicated eps = ti.random(float) ray_out_d = vec3([0, 1, 0]) spec = vec3([0, 0, 0]) - diffuse_color = ti.select(tex[0] < 0, self.k_d, tex) - pdf = diffuse_color.max() + pdf = ti.select(it.is_tex_invalid(), self.k_d, it.tex).max() # the max element of diffuse color is the pdf of sampling diffusive component if eps < pdf: # diffusive sampling - ray_out_d, spec, lmbt_pdf = self.sample_lambertian(normal, diffuse_color) # we use "texture" anyway, since it is converted + ray_out_d, spec, lmbt_pdf = self.sample_lambertian(it) # we use "texture" anyway, since it is converted pdf *= lmbt_pdf elif eps < pdf + self.k_s.max(): # specular sampling local_new_dir, pdf = mod_phong_hemisphere(self.mean[2]) - reflect_view = (-2 * normal * tm.dot(incid, normal) + incid).normalized() + reflect_view = (-2 * it.n_s * tm.dot(incid, it.n_s) + incid).normalized() ray_out_d, _ = delocalize_rotate(reflect_view, local_new_dir) - spec = self.eval_mod_phong(incid, ray_out_d, normal) + spec = self.eval_mod_phong(incid, ray_out_d, it.n_s) pdf *= self.k_s.max() else: # zero contribution # it doesn't matter even we don't return a valid ray_out_d @@ -192,23 +191,23 @@ def fresnel_cos2_sin2(self, half_vec: vec3, normal: vec3, R: mat3, dot_half: flo return cos_phi2, 1. - cos_phi2 @ti.func - def eval_fresnel_blend(self, ray_in: vec3, ray_out: vec3, normal: vec3, R: mat3, tex = INVALID): + def eval_fresnel_blend(self, it:ti.template(), ray_in: vec3, ray_out: vec3, R: mat3): # specular part, note that ray out is actually incident light in forward tracing half_vec = (ray_out - ray_in) - dot_out = tm.dot(normal, ray_out) + dot_out = tm.dot(it.n_s, ray_out) spec = vec3([0, 0, 0]) if dot_out > 0. and ti.abs(half_vec).max() > 1e-4: # ray_in and ray_out not on the exact opposite direction half_vec = half_vec.normalized() - dot_in = -tm.dot(normal, ray_in) # incident dot should always be positive (otherwise it won't hit this point) - dot_half = ti.abs(tm.dot(normal, half_vec)) + dot_in = -tm.dot(it.n_s, ray_in) # incident dot should always be positive (otherwise it won't hit this point) + dot_half = ti.abs(tm.dot(it.n_s, half_vec)) dot_hk = ti.abs(tm.dot(half_vec, ray_out)) fresnel = schlick_fresnel(self.k_s, dot_hk) - cos_phi2, sin_phi2 = self.fresnel_cos2_sin2(half_vec, normal, R, dot_half) + cos_phi2, sin_phi2 = self.fresnel_cos2_sin2(half_vec, it.n_s, R, dot_half) # k_g[2] should store sqrt((n_u + 1)(n_v + 1)) / 8pi denom = dot_hk * tm.max(dot_in, dot_out) specular = self.k_g[2] * tm.pow(dot_half, self.k_g[0] * cos_phi2 + self.k_g[1] * sin_phi2) * fresnel / denom # diffusive part - diffuse_color = ti.select(tex[0] < 0, self.k_d, tex) + diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, it.tex) diffuse = 28. / (23. * tm.pi) * diffuse_color * (1. - self.k_s) pow5_in = tm.pow(1. - dot_in / 2., 5) pow5_out = tm.pow(1. - dot_out / 2., 5) @@ -217,35 +216,35 @@ def eval_fresnel_blend(self, ray_in: vec3, ray_out: vec3, normal: vec3, R: mat3, return spec @ti.func - def sample_fresnel_blend(self, incid: vec3, normal: vec3, tex = INVALID): + def sample_fresnel_blend(self, it: ti.template(), incid: vec3): local_new_dir, power_coeff = fresnel_hemisphere(self.k_g[0], self.k_g[1]) - ray_half, R = delocalize_rotate(normal, local_new_dir) - ray_out_d, pdf, is_valid = self.fresnel_blend_dir(incid, ray_half, normal, power_coeff) + ray_half, R = delocalize_rotate(it.n_s, local_new_dir) + ray_out_d, pdf, is_valid = self.fresnel_blend_dir(incid, ray_half, it.n_s, power_coeff) if ti.random(float) > 0.5: - ray_out_d, _s, _p = self.sample_lambertian(normal, tex) - pdf = 0.5 * (pdf + ti.abs(tm.dot(ray_out_d, normal)) * INV_PI) - spec = ti.select(is_valid, self.eval_fresnel_blend(incid, ray_out_d, normal, R), ZERO_V3) + ray_out_d, _s, _p = self.sample_lambertian(it) + pdf = 0.5 * (pdf + ti.abs(tm.dot(ray_out_d, it.n_s)) * INV_PI) + spec = ti.select(is_valid, self.eval_fresnel_blend(it, incid, ray_out_d, R), ZERO_V3) return ray_out_d, spec, pdf # ======================= Lambertian ======================== @ti.func def eval_lambertian(self, it: ti.template(), ray_out: vec3): cosine_term = tm.max(0.0, tm.dot(ti.n_s, ray_out)) - diffuse_color = ti.select(tex[0] < 0, self.k_d, ti.tex) + diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, ti.tex) return diffuse_color * INV_PI * cosine_term @ti.func def sample_lambertian(self, it: ti.template()): local_new_dir, pdf = cosine_hemisphere() ray_out_d, _ = delocalize_rotate(it.n_s, local_new_dir) - spec = self.eval_lambertian(ray_out_d, it., tex) + spec = self.eval_lambertian(it, ray_out_d) return ray_out_d, spec, pdf # ======================= Mirror-Specular ======================== @ti.func - def sample_specular(self, ray_in: vec3, normal: vec3, tex = INVALID): - ray_out_d, _ = inci_reflect_dir(ray_in, normal) - return ray_out_d, ti.select(tex[0] < 0, self.k_d, tex), 1.0 + def sample_specular(self, it: ti.template(), ray_in: vec3): + ray_out_d, _ = inci_reflect_dir(ray_in, it.n_s) + return ray_out_d, ti.select(it.is_tex_invalid(), self.k_d, it.tex), 1.0 # ================================================================ @@ -258,14 +257,14 @@ def eval(self, it: ti.template(), incid: vec3, out: vec3) -> vec3: # For reflection, incident (in reverse direction) & outdir should be in the same hemisphere defined by the normal if tm.dot(incid, it.n_g) * tm.dot(out, it.n_g) < 0: if self._type == 0: # Blinn-Phong - ret_spec = self.eval_blinn_phong(incid, out, normal, tex) + ret_spec = self.eval_blinn_phong(it, incid, out) elif self._type == 1: # Lambertian - ret_spec = self.eval_lambertian(out, normal, tex) + ret_spec = self.eval_lambertian(it, out) elif self._type == 4: - ret_spec = self.eval_mod_phong(incid, out, normal) + ret_spec = self.eval_mod_phong(it, incid, out) elif self._type == 5: - R = rotation_between(vec3([0, 1, 0]), normal) - ret_spec = self.eval_fresnel_blend(incid, out, normal, R, tex) + R = rotation_between(vec3([0, 1, 0]), it.n_s) + ret_spec = self.eval_fresnel_blend(it, incid, out, R) return ret_spec @ti.func @@ -283,29 +282,30 @@ def sample_new_rays(self, it:ti.template(), incid: vec3): if self._type == 0: # Blinn-Phong ret_dir, ret_spec, pdf = self.sample_blinn_phong(it, incid) elif self._type == 1: # Lambertian - ret_dir, ret_spec, pdf = self.sample_lambertian(normal, tex) + ret_dir, ret_spec, pdf = self.sample_lambertian(it) elif self._type == 2: # Specular - specular has no cosine attenuation - ret_dir, ret_spec, pdf = self.sample_specular(incid, normal, tex) + ret_dir, ret_spec, pdf = self.sample_specular(it, incid) elif self._type == 4: # Modified-Phong - ret_dir, ret_spec, pdf = self.sample_mod_phong(incid, normal, tex) + ret_dir, ret_spec, pdf = self.sample_mod_phong(it, incid) elif self._type == 5: # Fresnel-Blend - ret_dir, ret_spec, pdf = self.sample_fresnel_blend(incid, normal, tex) + ret_dir, ret_spec, pdf = self.sample_fresnel_blend(it, incid) else: print(f"Warnning: unknown or unsupported BRDF type: {self._type} during sampling.") + # Prevent shading normal from light leaking or accidental shadowing ret_dot = tm.dot(ret_dir, it.n_g) ret_spec = ti.select(ret_dot > 0, ret_spec, 0.) return ret_dir, ret_spec, pdf @ti.func - def get_pdf(self, outdir: vec3, normal: vec3, incid: vec3, tex = INVALID): + def get_pdf(self, it: ti.template(), outdir: vec3, incid: vec3): """ Solid angle PDF for a specific incident direction - BRDF sampling Some PDF has nothing to do with backward incid (from eye to the surface), like diffusive This PDF is actually the PDF of cosine-weighted term * BRDF function value """ pdf = 0.0 - dot_outdir = tm.dot(normal, outdir) - dot_indir = tm.dot(normal, incid) + dot_outdir = tm.dot(it.n_s, outdir) + dot_indir = tm.dot(it.n_s, incid) if dot_outdir * dot_indir < 0.: # same hemisphere if self._type == 0: pdf = dot_outdir * INV_PI # dot is cosine term @@ -313,17 +313,17 @@ def get_pdf(self, outdir: vec3, normal: vec3, incid: vec3, tex = INVALID): pdf = dot_outdir * INV_PI elif self._type == 4: glossiness = self.mean[2] - reflect_view, _ = inci_reflect_dir(incid, normal) + reflect_view, _ = inci_reflect_dir(incid, it.n_s) dot_ref_out = tm.max(0., tm.dot(reflect_view, outdir)) diffuse_pdf = dot_outdir * INV_PI specular_pdf = 0.5 * (glossiness + 1.) * INV_PI * tm.pow(dot_ref_out, glossiness) - diffuse_color = ti.select(tex[0] < 0, self.k_d, tex) + diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, it.tex) pdf = diffuse_color.max() * diffuse_pdf + self.k_s.max() * specular_pdf elif self._type == 5: half_vec = (outdir - incid).normalized() - dot_half = tm.dot(half_vec, normal) - R = rotation_between(vec3([0, 1, 0]), normal) - cos_phi2, sin_phi2 = self.fresnel_cos2_sin2(half_vec, normal, R, dot_half) + dot_half = tm.dot(half_vec, it.n_s) + R = rotation_between(vec3([0, 1, 0]), it.n_s) + cos_phi2, sin_phi2 = self.fresnel_cos2_sin2(half_vec, it.n_s, R, dot_half) pdf = self.k_g[2] * tm.pow(dot_half, self.k_g[0] * cos_phi2 + self.k_g[1] * sin_phi2) / ti.abs(tm.dot(incid, half_vec)) pdf = 0.5 * (pdf + dot_outdir * INV_PI) return pdf \ No newline at end of file diff --git a/bxdf/bsdf.py b/bxdf/bsdf.py index e9b0198..9d6f5e3 100644 --- a/bxdf/bsdf.py +++ b/bxdf/bsdf.py @@ -22,6 +22,7 @@ from sampler.general_sampling import * from bxdf.brdf import BRDF_np from bxdf.medium import Medium, Medium_np +from tracer.interaction import Interaction from renderer.constants import TRANSPORT_RAD, INVALID __all__ = ['BSDF_np', 'BSDF'] @@ -74,13 +75,13 @@ class BSDF: # ========================= Deterministic Refraction ========================= @ti.func - def sample_det_refraction(self, incid: vec3, normal: vec3, medium, mode): + def sample_det_refraction(self, it: ti.template(), incid: vec3, medium, mode): """ Deterministic refraction sampling - Surface reflection is pure mirror specular \\ other (Medium) could be incident medium or refraction medium, depending on \\ whether the ray is entering or exiting the current BSDF """ - dot_normal = tm.dot(incid, normal) + dot_normal = tm.dot(incid, it.n_s) entering_this = dot_normal < 0 ni = ti.select(entering_this, medium.ior, self.medium.ior) nr = ti.select(entering_this, self.medium.ior, medium.ior) @@ -91,37 +92,38 @@ def sample_det_refraction(self, incid: vec3, normal: vec3, medium, mode): # ret_dir = (incid - 2 * normal * dot_normal).normalized() # we can account for total reflection... or not ret_int.fill(0.) else: - refra_vec, _v = snell_refraction(incid, normal, dot_normal, ni, nr) - reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_normal), ti.abs(tm.dot(refra_vec, normal))) + refra_vec, _v = snell_refraction(incid, it.n_s, dot_normal, ni, nr) + reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_normal), ti.abs(tm.dot(refra_vec, it.n_s))) if ti.random(float) > reflect_ratio: # refraction ret_pdf = 1. - reflect_ratio ret_dir = refra_vec if mode == TRANSPORT_RAD: # non-symmetry effect ret_int *= (ni * ni) / (nr * nr) else: # reflection - ret_dir = (incid - 2 * normal * dot_normal).normalized() + ret_dir = (incid - 2 * it.n_s * dot_normal).normalized() ret_pdf = reflect_ratio return ret_dir, ret_int * ret_pdf, ret_pdf @ti.func - def eval_det_refraction(self, ray_in: vec3, ray_out: vec3, normal: vec3, medium, mode, tex = INVALID): - dot_out = tm.dot(ray_out, normal) + def eval_det_refraction(self, it: ti.template(), ray_in: vec3, ray_out: vec3, medium, mode): + # I think this is counter-intuitive + dot_out = tm.dot(ray_out, it.n_s) entering_this = dot_out < 0 # notice that eval uses ray_out while sampling uses ray_in, therefore nr & ni have different order ni = ti.select(entering_this, medium.ior, self.medium.ior) nr = ti.select(entering_this, self.medium.ior, medium.ior) ret_int = vec3([0, 0, 0]) - diffuse_color = ti.select(tex[0] < 0, self.k_d, tex) + diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, it.tex) if is_total_reflection(dot_out, ni, nr): - ref_dir = (ray_out - 2 * normal * dot_out).normalized() + ref_dir = (ray_out - 2 * it.n_s * dot_out).normalized() if tm.dot(ref_dir, ray_in) > 1 - 5e-5: ret_int = diffuse_color else: # in sampling: ray_in points to the intersection, here ray_out points away from the intersection - ref_dir = (ray_out - 2 * normal * dot_out).normalized() - refra_vec, valid_ref = snell_refraction(ray_out, normal, dot_out, ni, nr) + ref_dir = (ray_out - 2 * it.n_s * dot_out).normalized() + refra_vec, valid_ref = snell_refraction(ray_out, it.n_s, dot_out, ni, nr) if valid_ref: - reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_out), ti.abs(tm.dot(refra_vec, normal))) + reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_out), ti.abs(tm.dot(refra_vec, it.n_s))) if tm.dot(refra_vec, ray_in) > 1 - 5e-5: # ray_in close to refracted dir ret_int = diffuse_color * (1. - reflect_ratio) if mode == TRANSPORT_RAD: # consider non-symmetric effect due to different transport mode @@ -135,20 +137,20 @@ def eval_det_refraction(self, ray_in: vec3, ray_out: vec3, normal: vec3, medium, # ========================= General operations ========================= @ti.func - def get_pdf(self, outdir: vec3, normal: vec3, incid: vec3, medium): + def get_pdf(self, it: ti.template(), outdir: vec3, incid: vec3, medium): pdf = 0. if self._type == -1: pdf = ti.select(tm.dot(incid, outdir) > 1 - 5e-5, 1., 0.) elif self._type == 0: - dot_out = tm.dot(outdir, normal) + dot_out = tm.dot(outdir, it.n_s) entering_this = dot_out < 0 # notice that eval uses ray_out while sampling uses ray_in, therefore nr & ni have different order ni = ti.select(entering_this, medium.ior, self.medium.ior) nr = ti.select(entering_this, self.medium.ior, medium.ior) - ref_dir = (outdir - 2 * normal * dot_out).normalized() - refra_vec, valid_refra = snell_refraction(outdir, normal, dot_out, ni, nr) + ref_dir = (outdir - 2 * it.n_s * dot_out).normalized() + refra_vec, valid_refra = snell_refraction(outdir, it.n_s, dot_out, ni, nr) if valid_refra: # not total reflection, so there is not only one possible choice - reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_out), ti.abs(tm.dot(refra_vec, normal))) + reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_out), ti.abs(tm.dot(refra_vec, it.n_s))) if tm.dot(refra_vec, incid) > 1 - 5e-5: # ray_in close to refracted dir pdf = 1. - reflect_ratio elif tm.dot(ref_dir, incid) > 1 - 5e-5: # ray_in close to reflected dir @@ -164,10 +166,10 @@ def is_non_null(self): # null surface is -1 # ========================= Surface interactions ============================ @ti.func - def eval_surf(self, incid: vec3, out: vec3, normal: vec3, medium, mode, tex = INVALID) -> vec3: + def eval_surf(self, it: ti.template(), incid: vec3, out: vec3, medium, mode) -> vec3: ret_spec = vec3([0, 0, 0]) if self._type == 0: - ret_spec = self.eval_det_refraction(incid, out, normal, medium, mode, tex) + ret_spec = self.eval_det_refraction(it, incid, out, medium, mode) return ret_spec @ti.func diff --git a/emitters/abtract_source.py b/emitters/abtract_source.py index dfcba97..0f67d06 100644 --- a/emitters/abtract_source.py +++ b/emitters/abtract_source.py @@ -211,10 +211,10 @@ def eval_le(self, inci_dir: vec3, normal: vec3): return ret_int @ti.func - def solid_angle_pdf(self, incid_dir: vec3, normal: vec3, depth: float): + def solid_angle_pdf(self, it: ti.template(), incid_dir: vec3): """ Area PDF converting to solid angle PDF (for hitting a area light) """ - dot_res = ti.abs(tm.dot(incid_dir, normal)) - return ti.select(dot_res > 0.0, self.area_pdf() * ti.pow(depth, 2) / dot_res, 0.0) + dot_res = ti.abs(tm.dot(incid_dir, it.n_s)) + return ti.select(dot_res > 0.0, self.area_pdf() * ti.pow(it.min_depth, 2) / dot_res, 0.0) @ti.func def area_pdf(self): diff --git a/renderer/path_utils.py b/renderer/path_utils.py index b6a7cd6..27c61c1 100644 --- a/renderer/path_utils.py +++ b/renderer/path_utils.py @@ -8,6 +8,7 @@ import taichi.math as tm from taichi.math import vec3 from renderer.constants import * +from tracer.interaction import Interaction @ti.func def remap_pdf(x: float) -> float: @@ -16,7 +17,7 @@ def remap_pdf(x: float) -> float: @ti.dataclass class Vertex: """ - A (64 + 12)-Byte Path Vertex + A (64 + 24)-Byte Path Vertex """ _type: ti.i8 """ 0 for surface, 1 for medium, 2 for light, 3 for camera """ @@ -33,7 +34,9 @@ class Vertex: time: float """ hit time (reserved for future uses) """ normal: vec3 - """ hit normal """ + """ hit normal (shading normal) """ + n_g: vec3 + """ hit normal (geometric normal) """ pos: vec3 """ hit pos """ ray_in: vec3 @@ -94,4 +97,9 @@ def not_delta(self): def not_delta_source(self): # if an emitter is positional delta or directional delta return (self.bool_bits & 0x03) == 0 + + @ti.experimental.real_func + def get_interaction(self) -> Interaction: + # FIXME: self.normal + return Interaction(obj_id = self.obj_id, n_s = self.normal, n_g = self.n_g, tex = self.tex) \ No newline at end of file diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index 2e8ab05..606e48a 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -73,7 +73,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int if self.does_intersect(light_dir, hit_point, emitter_d): # shadow ray shadow_int.fill(0.0) else: - direct_spec = self.eval(obj_id, ray_d, light_dir, normal, False, False, tex = tex) + direct_spec = self.eval(it, ray_d, light_dir, False, False) else: # the only situation for being invalid, is when there is only one source and the ray hit the source break_flag = True break @@ -81,7 +81,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int if ti.static(self.use_mis): mis_w = 1.0 if not emitter.is_delta_pos(): - bsdf_pdf = self.surface_pdf(obj_id, light_dir, normal, ray_d, tex = tex) + bsdf_pdf = self.surface_pdf(it, light_dir, ray_d) mis_w = balance_heuristic(light_pdf, bsdf_pdf) direct_int += direct_spec * shadow_int * mis_w / emitter_pdf else: @@ -91,22 +91,22 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int # emission: ray hitting an area light source emit_int = vec3([0, 0, 0]) if hit_light >= 0: - emit_int = self.src_field[hit_light].eval_le(hit_point - ray_o, normal) + emit_int = self.src_field[hit_light].eval_le(hit_point - ray_o, it.n_s) # indirect component requires sampling - ray_d, indirect_spec, ray_pdf = self.sample_new_ray(obj_id, ray_d, normal, False, False, tex = tex) + ray_d, indirect_spec, ray_pdf = self.sample_new_ray(it, ray_d, False, False) ray_o = hit_point color += (direct_int + emit_int * emission_weight) * contribution # VERY IMPORTANT: rendering should be done according to rendering equation (approximation) contribution *= indirect_spec / ray_pdf it = self.ray_intersect(ray_d, ray_o) - if obj_id >= 0: - hit_light = self.emitter_id[obj_id] + if it.obj_id >= 0: + hit_light = self.emitter_id[it.obj_id] if ti.static(self.use_mis): emitter_pdf = 0.0 - if hit_light >= 0 and self.is_delta(obj_id) == 0: - emitter_pdf = self.src_field[hit_light].solid_angle_pdf(ray_d, normal, min_depth) + if hit_light >= 0 and self.is_delta(it.obj_id) == 0: + emitter_pdf = self.src_field[hit_light].solid_angle_pdf(it, ray_d) emission_weight = balance_heuristic(ray_pdf, emitter_pdf) self.color[i, j] += ti.select(ti.math.isnan(color), 0., color) diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 7974f5d..669d060 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -61,8 +61,7 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.stratified_sample = prop['stratified_sampling'] # whether to use stratified sampling self.use_mis = prop['use_mis'] # whether to use multiple importance sampling self.num_shadow_ray = prop['num_shadow_ray'] # number of shadow samples to trace - # two sides BRDF (for some complex scene of which the normals might be incorrectly pointed) - self.brdf_two_sides = prop.get('brdf_two_sides', False) + if self.num_shadow_ray > 0: self.inv_num_shadow_ray = 1. / float(self.num_shadow_ray) else: @@ -399,10 +398,6 @@ def sample_new_ray(self, ret_dir, ret_spec, ret_pdf = self.bsdf_field[idx].medium.sample_new_rays(incid) else: # surface sampling if ti.is_active(self.brdf_nodes, idx): # active means the object is attached to BRDF - if ti.static(self.brdf_two_sides): - dot_res = tm.dot(incid, normal) - if dot_res > 0.: # two sides - normal *= -1 ret_dir, ret_spec, ret_pdf = self.brdf_field[idx].sample_new_rays(incid, normal, tex) else: # directly sample surface ret_dir, ret_spec, ret_pdf = self.bsdf_field[idx].sample_surf_rays(incid, normal, self.world.medium, mode) @@ -420,43 +415,31 @@ def eval(self, it: ti.template(), incid: vec3, out: vec3, is_mi: int, ret_spec.fill(self.bsdf_field[it.obj_id].medium.eval(incid, out)) else: # surface interaction if ti.is_active(self.brdf_nodes, it.obj_id): # active means the object is attached to BRDF - if ti.static(self.brdf_two_sides): - dot_res = tm.dot(incid, normal) - if dot_res > 0.: # two sides - normal *= -1 - ret_spec = self.brdf_field[it.obj_id].eval(incid, out, normal, tex) + ret_spec = self.brdf_field[it.obj_id].eval(it, incid, out) else: # directly evaluate surface ret_spec = self.bsdf_field[it.obj_id].eval_surf(incid, out, normal, self.world.medium, mode, tex) return ret_spec @ti.func - def surface_pdf(self, idx: int, outdir: vec3, normal: vec3, incid: vec3, tex: vec3 = INVALID): + def surface_pdf(self, it: ti.template(), outdir: vec3, incid: vec3): """ Outdir: actual incident ray direction, incid: ray (from camera) """ pdf = 0. - if ti.is_active(self.brdf_nodes, idx): # active means the object is attached to BRDF - if ti.static(self.brdf_two_sides): - dot_res = tm.dot(incid, normal) - if dot_res > 0.: # two sides - normal *= -1 - pdf = self.brdf_field[idx].get_pdf(outdir, normal, incid, tex) + if ti.is_active(self.brdf_nodes, it.obj_id): # active means the object is attached to BRDF + pdf = self.brdf_field[it.obj_id].get_pdf(it, outdir, incid) else: - pdf = self.bsdf_field[idx].get_pdf(outdir, normal, incid, self.world.medium) + pdf = self.bsdf_field[it.obj_id].get_pdf(outdir, normal, incid, self.world.medium) return pdf @ti.func - def get_pdf(self, idx: int, incid: vec3, out: vec3, normal: vec3, is_mi: int, in_free_space: int, tex: vec3 = INVALID): + def get_pdf(self, it: ti.template(), incid: vec3, out: vec3, is_mi: int, in_free_space: int): pdf = 0. if is_mi: # evaluate phase function if in_free_space: pdf = self.world.medium.eval(incid, out) else: - pdf = self.bsdf_field[idx].medium.eval(incid, out) + pdf = self.bsdf_field[it.obj_id].medium.eval(incid, out) else: - if ti.static(self.brdf_two_sides): - dot_res = tm.dot(incid, normal) - if dot_res > 0.: # two sides - normal *= -1 - pdf = self.surface_pdf(idx, out, normal, incid, tex) + pdf = self.surface_pdf(it, it.obj_id, out, incid) return pdf @ti.func From 0a3667084f24b19b813c03d8a40ad3186fb8872a Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Mon, 26 Jun 2023 00:46:43 +0800 Subject: [PATCH 06/18] Vertex normal partially okay, not correct with det-refract --- bxdf/brdf.py | 9 ++-- bxdf/bsdf.py | 16 +++--- emitters/abtract_source.py | 1 + renderer/bdpt.py | 2 +- renderer/path_utils.py | 2 +- renderer/vanilla_renderer.py | 8 +-- renderer/vpt.py | 4 +- scenes/cbox/cbox-vn.xml | 19 ++++--- tracer/path_tracer.py | 100 +++++++++++++++++++++++------------ tracer/tracer_base.py | 36 +++++++++---- 10 files changed, 125 insertions(+), 72 deletions(-) diff --git a/bxdf/brdf.py b/bxdf/brdf.py index 8b84547..dcea7dd 100644 --- a/bxdf/brdf.py +++ b/bxdf/brdf.py @@ -49,7 +49,6 @@ def __init__(self, elem: xet.Element, no_setup = False): self.kd_default = True self.ks_default = True self.kg_default = True - self.ka_default = True self.uv_coords = None texture_nodes = elem.findall("texture") @@ -93,7 +92,7 @@ def export(self): ) def __repr__(self) -> str: - return f"<{self.type.capitalize()} BRDF, default:[{int(self.kd_default), int(self.ks_default), int(self.kg_default), int(self.ka_default)}]>" + return f"<{self.type.capitalize()} BRDF, default:[{int(self.kd_default), int(self.ks_default), int(self.kg_default)}]>" @ti.dataclass class BRDF: @@ -160,7 +159,7 @@ def sample_mod_phong(self, it: ti.template(), incid: vec3): local_new_dir, pdf = mod_phong_hemisphere(self.mean[2]) reflect_view = (-2 * it.n_s * tm.dot(incid, it.n_s) + incid).normalized() ray_out_d, _ = delocalize_rotate(reflect_view, local_new_dir) - spec = self.eval_mod_phong(incid, ray_out_d, it.n_s) + spec = self.eval_mod_phong(it, incid, ray_out_d) pdf *= self.k_s.max() else: # zero contribution # it doesn't matter even we don't return a valid ray_out_d @@ -229,8 +228,8 @@ def sample_fresnel_blend(self, it: ti.template(), incid: vec3): # ======================= Lambertian ======================== @ti.func def eval_lambertian(self, it: ti.template(), ray_out: vec3): - cosine_term = tm.max(0.0, tm.dot(ti.n_s, ray_out)) - diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, ti.tex) + cosine_term = tm.max(0.0, tm.dot(it.n_s, ray_out)) + diffuse_color = ti.select(it.is_tex_invalid(), self.k_d, it.tex) return diffuse_color * INV_PI * cosine_term @ti.func diff --git a/bxdf/bsdf.py b/bxdf/bsdf.py index 9d6f5e3..840280d 100644 --- a/bxdf/bsdf.py +++ b/bxdf/bsdf.py @@ -22,8 +22,7 @@ from sampler.general_sampling import * from bxdf.brdf import BRDF_np from bxdf.medium import Medium, Medium_np -from tracer.interaction import Interaction -from renderer.constants import TRANSPORT_RAD, INVALID +from renderer.constants import TRANSPORT_RAD __all__ = ['BSDF_np', 'BSDF'] @@ -82,15 +81,16 @@ def sample_det_refraction(self, it: ti.template(), incid: vec3, medium, mode): whether the ray is entering or exiting the current BSDF """ dot_normal = tm.dot(incid, it.n_s) + # at least according to pbrt-v3, ni / nr is computed as the following (using shading normal) + # see https://computergraphics.stackexchange.com/questions/13540/shading-normal-and-geometric-normal-for-refractive-surface-rendering entering_this = dot_normal < 0 ni = ti.select(entering_this, medium.ior, self.medium.ior) nr = ti.select(entering_this, self.medium.ior, medium.ior) ret_pdf = 1.0 ret_dir = vec3([0, 1, 0]) - ret_int = self.k_d + ret_int = it.tex if is_total_reflection(dot_normal, ni, nr): - # ret_dir = (incid - 2 * normal * dot_normal).normalized() # we can account for total reflection... or not - ret_int.fill(0.) + ret_dir = (incid - 2 * it.n_s * dot_normal).normalized() else: refra_vec, _v = snell_refraction(incid, it.n_s, dot_normal, ni, nr) reflect_ratio = fresnel_equation(ni, nr, ti.abs(dot_normal), ti.abs(tm.dot(refra_vec, it.n_s))) @@ -106,7 +106,6 @@ def sample_det_refraction(self, it: ti.template(), incid: vec3, medium, mode): @ti.func def eval_det_refraction(self, it: ti.template(), ray_in: vec3, ray_out: vec3, medium, mode): - # I think this is counter-intuitive dot_out = tm.dot(ray_out, it.n_s) entering_this = dot_out < 0 # notice that eval uses ray_out while sampling uses ray_in, therefore nr & ni have different order @@ -173,12 +172,11 @@ def eval_surf(self, it: ti.template(), incid: vec3, out: vec3, medium, mode) -> return ret_spec @ti.func - def sample_surf_rays(self, incid: vec3, normal: vec3, medium, mode): - # TODO: we need mode here (and in eval) + def sample_surf_rays(self, it: ti.template(), incid: vec3, medium, mode): ret_dir = vec3([0, 0, 0]) ret_spec = vec3([0, 0, 0]) pdf = 0.0 if self._type == 0: - ret_dir, ret_spec, pdf = self.sample_det_refraction(incid, normal, medium, mode) + ret_dir, ret_spec, pdf = self.sample_det_refraction(it, incid, medium, mode) return ret_dir, ret_spec, pdf \ No newline at end of file diff --git a/emitters/abtract_source.py b/emitters/abtract_source.py index 0f67d06..66e07d8 100644 --- a/emitters/abtract_source.py +++ b/emitters/abtract_source.py @@ -2,6 +2,7 @@ Light source abstraction @date: 2023.1.20 @author: Qianyue He + @note: I think for emitters, there is no point using shading normal (2023.6.25) """ import sys diff --git a/renderer/bdpt.py b/renderer/bdpt.py index d5bef15..2c89a1a 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -263,7 +263,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: is_delta = (not is_mi) and self.is_delta(obj_id) bool_bits = BDPT.get_bool(d_delta = is_delta, is_area = (hit_light >= 0), in_fspace = in_free_space, is_delta = is_delta) - tex = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) + tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) vertex_args = {"_type": ti.select(is_mi, VERTEX_MEDIUM, VERTEX_SURFACE), "obj_id": obj_id, "emit_id": hit_light, "bool_bits": bool_bits, "pdf_fwd": pdf_fwd, "time": acc_time, "pos": hit_point, "normal": ti.select(is_mi, ZERO_V3, normal), "ray_in": ray_d, "beta": throughput, "tex": tex diff --git a/renderer/path_utils.py b/renderer/path_utils.py index 27c61c1..95f91f8 100644 --- a/renderer/path_utils.py +++ b/renderer/path_utils.py @@ -98,7 +98,7 @@ def not_delta_source(self): # if an emitter is positional delta or directional delta return (self.bool_bits & 0x03) == 0 - @ti.experimental.real_func + @ti.func def get_interaction(self) -> Interaction: # FIXME: self.normal return Interaction(obj_id = self.obj_id, n_s = self.normal, n_g = self.n_g, tex = self.tex) diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index 606e48a..e1e1cdf 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -35,13 +35,14 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int ray_d = self.pix2ray(i, j) ray_o = self.cam_t it = self.ray_intersect(ray_d, ray_o) - # obj_id, normal, min_depth, prim_id, u_coord, v_coord + self.process_ns(it) # (possibly) get normal map / bump map + hit_light = self.emitter_id[ti.max(it.obj_id, 0)] # id for hit emitter, if nothing is hit, this value will be -1 color = vec3([0, 0, 0]) contribution = vec3([1, 1, 1]) emission_weight = 1.0 for _i in range(self.max_bounce): - if it.is_ray_not_hit() < 0: break # nothing is hit, break + if it.is_ray_not_hit(): break # nothing is hit, break if ti.static(self.use_rr): # Simple Russian Roullete ray termination max_value = contribution.max() @@ -57,7 +58,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - it.tex = self.get_uv_item(self.albedo_map, self.albedo_img, it) + it.tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) @@ -69,6 +70,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int emitter_d = to_emitter.norm() light_dir = to_emitter / emitter_d # Note that, null surface in vanilla renderer will produce erroneous results + # FIXME: Qianyue He's note on 2023.6.25: why erroneous results? # TODO: for collimated light, this is more complicated --- intersection test and the direction of ray should be modified if self.does_intersect(light_dir, hit_point, emitter_d): # shadow ray shadow_int.fill(0.0) diff --git a/renderer/vpt.py b/renderer/vpt.py index f1f27fd..409d6a8 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -48,7 +48,7 @@ def get_transmittance(self, idx: int, in_free_space: int, depth: float): def non_null_surface(self, idx: int): non_null = True # All these idx >= 0 check is for world scattering medium - if idx >= 0 and not ti.is_active(self.brdf_nodes, idx): # BRDF is non-null, BSDF can be non-null + if idx >= 0 and not ti.is_active(self.obj_nodes, idx): # BRDF is non-null, BSDF can be non-null non_null = self.bsdf_field[idx].is_non_null() return non_null @@ -162,7 +162,7 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) + tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) diff --git a/scenes/cbox/cbox-vn.xml b/scenes/cbox/cbox-vn.xml index bacfde4..e829903 100755 --- a/scenes/cbox/cbox-vn.xml +++ b/scenes/cbox/cbox-vn.xml @@ -17,6 +17,7 @@ + @@ -63,6 +64,16 @@ + + + + + + + + + + @@ -100,18 +111,12 @@ - - - - - - - + diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 669d060..5eb7bd3 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -22,7 +22,7 @@ from bxdf.brdf import BRDF from bxdf.bsdf import BSDF, BSDF_np -from bxdf.texture import Texture +from bxdf.texture import Texture, Texture_np from parsers.opts import get_options from parsers.obj_desc import ObjDescriptor from parsers.xml_parser import scene_parsing @@ -72,7 +72,6 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.emitter_id = ti.field(int, self.num_objects) self.src_num = len(emitters) - self.v_normals = ti.Vector.field(3, float) self.color = ti.Vector.field(3, float, (self.w, self.h)) # color without normalization self.src_field = TaichiSource.field() self.brdf_field = BRDF.field() @@ -88,16 +87,20 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.roughness_map = Texture.field() # TODO: this is useless for now ti.root.dense(ti.i, self.src_num).place(self.src_field) # Light source Taichi storage - self.brdf_nodes = ti.root.bitmasked(ti.i, self.num_objects) - self.brdf_nodes.place(self.brdf_field) # BRDF Taichi storage + self.obj_nodes = ti.root.bitmasked(ti.i, self.num_objects) + self.obj_nodes.place(self.brdf_field) # BRDF Taichi storage ti.root.bitmasked(ti.i, self.num_objects).place(self.bsdf_field) # BRDF Taichi storage (no node needed) - ti.root.bitmasked(ti.i, self.num_objects).place(self.albedo_map, self.normal_map, self.bump_map, self.roughness_map) + ti.root.dense(ti.i, self.num_objects).place(self.albedo_map, self.normal_map, self.bump_map, self.roughness_map) if prop["packed_textures"] is None: self.albedo_img = ti.Vector.field(3, float, (1, 1)) self.normal_img = ti.Vector.field(3, float, (1, 1)) self.bump_img = ti.Vector.field(3, float, (1, 1)) self.roughness_img = ti.Vector.field(3, float, (1, 1)) + self.has_albedo_map = False + self.has_normal_map = False + self.has_bump_map = False + self.has_roughness_map = False else: images = prop["packed_texture"] # dict ('albedo': Optional(), 'normal': ...) for key, image in images.item(): @@ -105,17 +108,11 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.__setattr__(f"{key}_img", ti.Vector.field(3, float, (1, 1))) continue tex_h, tex_w, _ = image.shape + self.__setattr__(f"has_{key}_map", True) self.__setattr__(f"{key}_img", ti.Vector.field(3, float, (tex_w, tex_h))) self.__getattribute__(f"{key}_img").from_numpy(image) CONSOLE.log(f"Packed texture image tagged '{key}' loaded: ({tex_w}, {tex_h})") - self.has_v_normal = prop["has_vertex_normal"] - if prop["has_vertex_normal"]: - CONSOLE.log(f"Vertex normals found. Allocating storage for v-normals.") - self.prim_handle.place(self.v_normals) # actual vertex normal storage - else: - ti.root.bitmasked(ti.i, 1).place(self.v_normals) # A dummy place - CONSOLE.log(f"Path tracer param loading in {self.clock.toc_tic(True):.3f} ms") self.initialze(emitters, objects) CONSOLE.log(f"Path tracer initialization in {self.clock.toc(True):.3f} ms") @@ -234,9 +231,9 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): self.uv_coords[cur_id, 2] = vec2(uv_coord[2]) if obj.vns is not None: vn = obj.vns[j] - self.v_normals[cur_id, 0] = vec2(vn[0]) - self.v_normals[cur_id, 1] = vec2(vn[1]) - self.v_normals[cur_id, 2] = vec2(vn[2]) + self.v_normals[cur_id, 0] = vec3(vn[0]) + self.v_normals[cur_id, 1] = vec3(vn[1]) + self.v_normals[cur_id, 2] = vec3(vn[2]) self.obj_info[i, 0] = acc_prim_num self.obj_info[i, 1] = obj.tri_num @@ -251,6 +248,8 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): for key, value in obj.texture_group.items(): # exporting texture group if value is not None: self.__getattribute__(f"{key}_map")[i] = value.export() + else: + self.__getattribute__(f"{key}_map")[i] = Texture_np.default() self.aabbs[i, 0] = vec3(obj.aabb[0]) # unrolled self.aabbs[i, 1] = vec3(obj.aabb[1]) @@ -262,13 +261,35 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): @ti.func def get_uv_item(self, textures: ti.template(), tex_img: ti.template(), it: ti.template()): """ Convert primitive local UV to the global UV coord for an object """ - it.tex = INVALID - if ti.is_active(textures, it.obj_id): + tex_value = INVALID + valid = False + if it.obj_id >= 0 and textures[it.obj_id].type > -255: + u, v = it.uv # local u and local v is_sphere = self.obj_info[it.obj_id, 2] if is_sphere == 0: # not a sphere u, v = self.uv_coords[it.prim_id, 1] * u + self.uv_coords[it.prim_id, 2] * v + \ - self.uv_coords[it.prim_id, 0] * (1. - u - v) - it.tex = textures[it.obj_id].query(tex_img, u, v) + self.uv_coords[it.prim_id, 0] * (1. - u - v) # convert from local to global + tex_value = textures[it.obj_id].query(tex_img, u, v) + valid = True + return tex_value, valid + + @ti.func + def process_ns(self, it: ti.template()): + """ Process shading normal for interaction + For example, we may have bump map / normal map + We should convert the normal from local frame to global frame + normal map: replace the original shading normal with normal map normal + bump map: apply a rotational offset to the current shading normal + """ + if ti.static(self.has_normal_map): + normal, n_valid = self.get_uv_item(self.normal_map, self.normal_img, it) + if n_valid: + R = rotation_between(vec3([0, 1, 0]), it.n_g) + it.n_s = (R @ normal).normalized() + if ti.static(self.has_bump_map): + delta_n, d_valid = self.get_uv_item(self.bump_map, self.bump_img, it) + if d_valid: + it.n_s, _ = delocalize_rotate(it.n_s, delta_n) @ti.func def bvh_intersect(self, bvh_id, ray, start_p): @@ -291,9 +312,9 @@ def bvh_intersect(self, bvh_id, ray, start_p): ray_t += ti.select(center_norm2 > radius2 + 1e-4, -ray_cut, ray_cut) else: p1 = self.prims[prim_idx, 0] - vec1 = self.precom_vec[prim_idx, 0] - vec2 = self.precom_vec[prim_idx, 1] - mat = ti.Matrix.cols([vec1, vec2, -ray]).inverse() + v1 = self.precom_vec[prim_idx, 0] + v2 = self.precom_vec[prim_idx, 1] + mat = ti.Matrix.cols([v1, v2, -ray]).inverse() u, v, t = mat @ (start_p - p1) # u, v as barycentric coordinates should be returned if u >= 0 and v >= 0 and u + v <= 1.0: @@ -335,17 +356,26 @@ def ray_intersect_bvh(self, ray: vec3, start_p, min_depth = -1.0): coord_v = v node_idx += 1 n_g = vec3([1, 0, 0]) + n_s = vec3([1, 0, 0]) if obj_id >= 0: if sphere_flag: center = self.prims[prim_id, 0] n_g = (start_p + min_depth * ray - center).normalized() coord_u = (tm.atan2(n_g[1], n_g[0]) + tm.pi) * INV_2PI coord_v = tm.acos(n_g[2]) * INV_PI + n_s = n_g else: n_g = self.normals[prim_id] + # calculate vertex normal (for shading) if vertex normal exists + if ti.static(self.has_v_normal): + n_s = self.v_normals[prim_id, 0] * (1. - coord_u - coord_v) + \ + coord_u * self.v_normals[prim_id, 1] + \ + coord_v * self.v_normals[prim_id, 2] + else: + n_s = n_g # The returned coord_u and coord_v is not the actual uv coords (but for one specific primitive) return Interaction( - obj_id = obj_id, prim_id = prim_id, n_g = n_g, n_s = n_g, + obj_id = obj_id, prim_id = prim_id, n_g = n_g, n_s = n_s, uv = vec2(coord_u, coord_v), min_depth = min_depth ) @@ -379,8 +409,8 @@ def does_intersect_bvh(self, ray, start_p, min_depth = -1.0): @ti.func def sample_new_ray(self, - idx: int, incid: vec3, normal: vec3, is_mi: int, - in_free_space: int, mode: int = TRANSPORT_UNI, tex: vec3 = INVALID + it: ti.template(), incid: vec3, is_mi: int, + in_free_space: int, mode: int = TRANSPORT_UNI ): """ Mode is for cosine term calculation: \\ For camera path, cosine term is computed against (ray_out and normal), \\ @@ -395,12 +425,12 @@ def sample_new_ray(self, if in_free_space: # sample world medium ret_dir, ret_spec, ret_pdf = self.world.medium.sample_new_rays(incid) else: # sample object medium - ret_dir, ret_spec, ret_pdf = self.bsdf_field[idx].medium.sample_new_rays(incid) + ret_dir, ret_spec, ret_pdf = self.bsdf_field[it.obj_id].medium.sample_new_rays(incid) else: # surface sampling - if ti.is_active(self.brdf_nodes, idx): # active means the object is attached to BRDF - ret_dir, ret_spec, ret_pdf = self.brdf_field[idx].sample_new_rays(incid, normal, tex) + if ti.is_active(self.obj_nodes, it.obj_id): # active means the object is attached to BRDF + ret_dir, ret_spec, ret_pdf = self.brdf_field[it.obj_id].sample_new_rays(it, incid) else: # directly sample surface - ret_dir, ret_spec, ret_pdf = self.bsdf_field[idx].sample_surf_rays(incid, normal, self.world.medium, mode) + ret_dir, ret_spec, ret_pdf = self.bsdf_field[it.obj_id].sample_surf_rays(it, incid, self.world.medium, mode) return ret_dir, ret_spec, ret_pdf @ti.func @@ -414,20 +444,20 @@ def eval(self, it: ti.template(), incid: vec3, out: vec3, is_mi: int, else: # is_mi implys is_scattering = True ret_spec.fill(self.bsdf_field[it.obj_id].medium.eval(incid, out)) else: # surface interaction - if ti.is_active(self.brdf_nodes, it.obj_id): # active means the object is attached to BRDF + if ti.is_active(self.obj_nodes, it.obj_id): # active means the object is attached to BRDF ret_spec = self.brdf_field[it.obj_id].eval(it, incid, out) else: # directly evaluate surface - ret_spec = self.bsdf_field[it.obj_id].eval_surf(incid, out, normal, self.world.medium, mode, tex) + ret_spec = self.bsdf_field[it.obj_id].eval_surf(it, incid, out, self.world.medium, mode) return ret_spec @ti.func def surface_pdf(self, it: ti.template(), outdir: vec3, incid: vec3): """ Outdir: actual incident ray direction, incid: ray (from camera) """ pdf = 0. - if ti.is_active(self.brdf_nodes, it.obj_id): # active means the object is attached to BRDF + if ti.is_active(self.obj_nodes, it.obj_id): # active means the object is attached to BRDF pdf = self.brdf_field[it.obj_id].get_pdf(it, outdir, incid) else: - pdf = self.bsdf_field[it.obj_id].get_pdf(outdir, normal, incid, self.world.medium) + pdf = self.bsdf_field[it.obj_id].get_pdf(it, outdir, incid, self.world.medium) return pdf @ti.func @@ -456,7 +486,7 @@ def is_delta(self, idx: int): # REAL FUNC is_delta = False if idx >= 0: - if ti.is_active(self.brdf_nodes, idx): # active means the object is attached to BRDF + if ti.is_active(self.obj_nodes, idx): # active means the object is attached to BRDF is_delta = self.brdf_field[idx].is_delta else: is_delta = self.bsdf_field[idx].is_delta @@ -467,7 +497,7 @@ def is_scattering(self, idx: int): # check if the object with index id # FIXME: if sigma_t is too small, set the scattering medium to det-refract # REAL FUNC is_scattering = False - if idx >= 0 and not ti.is_active(self.brdf_nodes, idx): + if idx >= 0 and not ti.is_active(self.obj_nodes, idx): is_scattering = self.bsdf_field[idx].medium.is_scattering() return is_scattering diff --git a/tracer/tracer_base.py b/tracer/tracer_base.py index b585f79..c3a8717 100644 --- a/tracer/tracer_base.py +++ b/tracer/tracer_base.py @@ -11,7 +11,7 @@ import numpy as np import taichi as ti import taichi.math as tm -from taichi.math import vec3, mat3 +from taichi.math import vec2, vec3, mat3 from typing import List from la.cam_transform import * @@ -21,6 +21,9 @@ from parsers.xml_parser import scene_parsing from renderer.constants import INV_PI, INV_2PI +from rich.console import Console +CONSOLE = Console(width = 128) + __eps__ = 1e-4 __inv_eps__ = 1 - __eps__ * 2. @@ -78,6 +81,7 @@ def __init__(self, objects: List[ObjDescriptor], prop: dict): self.prims = ti.Vector.field(3, float) # leveraging SSDS, shape (N, mesh_num, 3) - vector3d self.uv_coords = ti.Vector.field(2, float) # uv coordinates self.precom_vec = ti.Vector.field(3, float) + self.v_normals = ti.Vector.field(3, float) self.pixels = ti.Vector.field(3, float, (self.w, self.h)) # output: color self.dense_nodes = ti.root.dense(ti.i, self.num_prims) @@ -86,7 +90,12 @@ def __init__(self, objects: List[ObjDescriptor], prop: dict): self.prim_handle = self.dense_nodes.dense(ti.j, 3) self.prim_handle.place(self.prims, self.precom_vec) # for simple shapes, this would be efficient self.prim_handle.place(self.uv_coords) - self.has_v_normal = False + self.has_v_normal = prop["has_vertex_normal"] + if prop["has_vertex_normal"]: + CONSOLE.log(f"Vertex normals found. Allocating storage for v-normals.") + self.prim_handle.place(self.v_normals) # actual vertex normal storage + else: + ti.root.bitmasked(ti.i, 1).place(self.v_normals) # A dummy place # pos0: start_idx, pos1: number of primitives, pos2: obj_id (being triangle / sphere? Others to be added, like cylinder, etc.) self.obj_info = ti.field(int, (self.num_objects, 3)) @@ -172,9 +181,9 @@ def ray_intersect(self, ray, start_p, min_depth = -1.0): tri_num = self.obj_info[aabb_idx, 1] for mesh_idx in range(start_id, tri_num + start_id): p1 = self.prims[mesh_idx, 0] - vec1 = self.precom_vec[mesh_idx, 0] - vec2 = self.precom_vec[mesh_idx, 1] - mat = ti.Matrix.cols([vec1, vec2, -ray]).inverse() + v1 = self.precom_vec[mesh_idx, 0] + v2 = self.precom_vec[mesh_idx, 1] + mat = ti.Matrix.cols([v1, v2, -ray]).inverse() u, v, t = mat @ (start_p - p1) if u >= 0 and v >= 0 and u + v <= 1.0: if t > 1e-4 and t < min_depth: @@ -185,17 +194,26 @@ def ray_intersect(self, ray, start_p, min_depth = -1.0): coord_v = v sphere_flag = False n_g = vec3([1, 0, 0]) + n_s = vec3([1, 0, 0]) if obj_id >= 0: if sphere_flag: center = self.prims[prm_id, 0] n_g = (start_p + min_depth * ray - center).normalized() coord_u = (tm.atan2(n_g[1], n_g[0]) + tm.pi) * INV_2PI coord_v = tm.acos(n_g[2]) * INV_PI + n_s = n_g else: n_g = self.normals[prm_id] + # calculate vertex normal (for shading) if vertex normal exists + if ti.static(self.has_v_normal): + n_s = self.v_normals[prm_id, 0] * (1. - coord_u - coord_v) + \ + coord_u * self.v_normals[prm_id, 1] + \ + coord_v * self.v_normals[prm_id, 2] + else: + n_s = n_g # We should calculate global uv and n_s outside return Interaction( - obj_id = obj_id, prim_id = prm_id, n_g = n_g, n_s = n_g, + obj_id = obj_id, prim_id = prm_id, n_g = n_g, n_s = n_s, uv = vec2(coord_u, coord_v), min_depth = min_depth ) @@ -229,9 +247,9 @@ def does_intersect(self, ray, start_p, min_depth = -1.0): tri_num = self.obj_info[aabb_idx, 1] for mesh_idx in range(start_id, tri_num + start_id): p1 = self.prims[mesh_idx, 0] - vec1 = self.precom_vec[mesh_idx, 0] - vec2 = self.precom_vec[mesh_idx, 1] - mat = ti.Matrix.cols([vec1, vec2, -ray]).inverse() + v1 = self.precom_vec[mesh_idx, 0] + v2 = self.precom_vec[mesh_idx, 1] + mat = ti.Matrix.cols([v1, v2, -ray]).inverse() u, v, t = mat @ (start_p - p1) if u >= 0 and v >= 0 and u + v <= 1.0: if t > 1e-4 and t < min_depth: From cb5f617f5688eeff9ab69b5534627bba9b8ab77e Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Tue, 27 Jun 2023 00:41:21 +0800 Subject: [PATCH 07/18] vpt finished (not tested, MIS added). BDPT WIP --- bxdf/bsdf.py | 2 +- renderer/bdpt.py | 60 ++++++++++++++++++--------------- renderer/vpt.py | 77 ++++++++++++++++++++++++++++--------------- tracer/path_tracer.py | 5 +-- 4 files changed, 87 insertions(+), 57 deletions(-) diff --git a/bxdf/bsdf.py b/bxdf/bsdf.py index 840280d..67ac375 100644 --- a/bxdf/bsdf.py +++ b/bxdf/bsdf.py @@ -88,7 +88,7 @@ def sample_det_refraction(self, it: ti.template(), incid: vec3, medium, mode): nr = ti.select(entering_this, self.medium.ior, medium.ior) ret_pdf = 1.0 ret_dir = vec3([0, 1, 0]) - ret_int = it.tex + ret_int = ti.select(it.is_tex_invalid(), self.k_d, it.tex) if is_total_reflection(dot_normal, ni, nr): ret_dir = (incid - 2 * it.n_s * dot_normal).normalized() else: diff --git a/renderer/bdpt.py b/renderer/bdpt.py index 2c89a1a..040ef1f 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -229,44 +229,45 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: while True: # Step 1: ray intersection - obj_id, normal, min_depth, prim_id, u_coord, v_coord = self.ray_intersect(ray_d, ray_o) + it = self.ray_intersect(ray_d, ray_o) - if obj_id < 0: + if it.obj_id < 0: if not self.world_scattering: break # nothing is hit, break else: # the world is filled with scattering medium # TODO: This may not be totally correct, should be double-checked min_depth = self.world_bound_time(ray_o, ray_d) in_free_space = True - obj_id = -1 + it.obj_id = -1 else: - in_free_space = tm.dot(normal, ray_d) < 0 + in_free_space = tm.dot(it.n_g, ray_d) < 0 # Step 2: check for mean free path sampling # Calculate mfp, path_beta = transmittance / PDF - is_mi, min_depth, path_beta = self.sample_mfp(obj_id, in_free_space, min_depth) - if obj_id < 0 and not is_mi: break # exiting world bound + is_mi, min_depth, path_beta = self.sample_mfp(it.obj_id, in_free_space, min_depth) + if it.obj_id < 0 and not is_mi: break # exiting world bound throughput *= path_beta # attenuate first if throughput.max() < 5e-5: break hit_point = ray_d * min_depth + ray_o - hit_light = -1 if is_mi else self.emitter_id[obj_id] - acc_time += min_depth * self.get_ior(obj_id, in_free_space) + hit_light = -1 if is_mi else self.emitter_id[it.obj_id] + acc_time += min_depth * self.get_ior(it.obj_id, in_free_space) # Do not place vertex on null surface (no correct answer about whether it's surface or medium) - if not is_mi and not self.non_null_surface(obj_id): # surface interaction for null surface should be skipped + if not is_mi and not self.non_null_surface(it.obj_id): # surface interaction for null surface should be skipped ray_o = hit_point continue # Step 3: Create a new vertex and calculate pdf_fwd - pdf_fwd = BDPT.convert_density(ray_pdf, hit_point - last_v_pos, normal, is_mi) + pdf_fwd = BDPT.convert_density(ray_pdf, hit_point - last_v_pos, it.n_s, is_mi) last_v_pos = hit_point - is_delta = (not is_mi) and self.is_delta(obj_id) + is_delta = (not is_mi) and self.is_delta(it.obj_id) bool_bits = BDPT.get_bool(d_delta = is_delta, is_area = (hit_light >= 0), in_fspace = in_free_space, is_delta = is_delta) - tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) - vertex_args = {"_type": ti.select(is_mi, VERTEX_MEDIUM, VERTEX_SURFACE), "obj_id": obj_id, "emit_id": hit_light, + tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) + vertex_args = {"_type": ti.select(is_mi, VERTEX_MEDIUM, VERTEX_SURFACE), "obj_id": it.obj_id, "emit_id": hit_light, "bool_bits": bool_bits, "pdf_fwd": pdf_fwd, "time": acc_time, "pos": hit_point, - "normal": ti.select(is_mi, ZERO_V3, normal), "ray_in": ray_d, "beta": throughput, "tex": tex + "normal": ti.select(is_mi, ZERO_V3, it.n_s), "n_g": ti.select(is_mi, ZERO_V3, it.n_g), + "ray_in": ray_d, "beta": throughput, "tex": tex } vertex_num += 1 if transport_mode == TRANSPORT_IMP: # Camera path @@ -283,7 +284,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: # Step 5: sample new ray. This should distinguish between surface and medium interactions old_ray_d = ray_d - ray_d, indirect_spec, ray_pdf = self.sample_new_ray(obj_id, old_ray_d, normal, is_mi, in_free_space, transport_mode, tex) + ray_d, indirect_spec, ray_pdf = self.sample_new_ray(it, old_ray_d, is_mi, in_free_space, transport_mode) ray_o = hit_point pdf_bwd = ray_pdf if not is_mi: @@ -294,7 +295,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: pdf_bwd = 0. else: # Step 6: re-evaluate backward PDF - pdf_bwd = self.surface_pdf(obj_id, -old_ray_d, normal, -ray_d, tex) + pdf_bwd = self.surface_pdf(it, -old_ray_d, -ray_d) # ray_o is the position of the current vertex, which is used in prev vertex pdf_bwd if transport_mode == TRANSPORT_IMP: # Camera transport mode @@ -317,7 +318,7 @@ def connect_path(self, i: int, j: int, sid: int, tid: int, decomp: int): if sid == 0: # light path is not used vertex = self.cam_paths[i, j, tid - 1] if vertex.is_light(): # is the current vertex an emitter vertex? - le = self.src_field[int(vertex.emit_id)].eval_le(vertex.ray_in, vertex.normal) * vertex.beta + le = self.src_field[int(vertex.emit_id)].eval_le(vertex.ray_in, vertex.n_g) * vertex.beta ret_time = self.src_field[int(vertex.emit_id)].emit_time + vertex.time # for emission, we should acount for their emission time elif tid == 1: # re-rasterize point onto the film, atomic add is allowed vertex = self.light_paths[i, j, sid - 1] @@ -330,11 +331,13 @@ def connect_path(self, i: int, j: int, sid: int, tid: int, decomp: int): track_pos = vertex.pos # camera importance is valid / visible / radiance transferable if cam_pdf > 0: - fr2cam = self.eval(int(vertex.obj_id), vertex.ray_in, connect_dir, - vertex.normal, vertex.is_mi(), in_free_space, TRANSPORT_IMP, vertex.tex) + vit = vertex.get_interaction() + fr2cam = self.eval(vit, vertex.ray_in, connect_dir, + vertex.is_mi(), in_free_space, TRANSPORT_IMP) bool_bits = BDPT.get_bool(True, in_fspace = self.free_space_cam) sampled_v = Vertex(_type = VERTEX_CAMERA, obj_id = -1, emit_id = -1, - bool_bits = bool_bits, time = vertex.time + depth, normal = self.cam_normal, + bool_bits = bool_bits, time = vertex.time + depth, + normal = self.cam_normal, n_g = self.cam_normal, pos = self.cam_t, ray_in = ZERO_V3, beta = we / cam_pdf, tex = INVALID ) vertex_sampled = True @@ -355,13 +358,14 @@ def connect_path(self, i: int, j: int, sid: int, tid: int, decomp: int): in_free_space = vertex.is_in_free_space() # emitter should have non-zero emission / visible / transferable if emit_int.max() > 0: - fr2light = self.eval(int(vertex.obj_id), vertex.ray_in, connect_dir, - vertex.normal, vertex.is_mi(), in_free_space, TRANSPORT_RAD, vertex.tex) + vit = vertex.get_interaction() + fr2light = self.eval(vit, vertex.ray_in, connect_dir, + vertex.is_mi(), in_free_space, TRANSPORT_RAD) # We should apply texture on the emitter, so get color should be computed here # Sample hit should also return uv coords sampled_v = Vertex(_type = VERTEX_EMITTER, obj_id = self.get_associated_obj(emit_id), emit_id = emit_id, bool_bits = emitter.bool_bits, time = emitter.emit_time, pdf_fwd = emitter.area_pdf() / float(self.src_num), - normal = normal, pos = emit_pos, ray_in = ZERO_V3, beta = emit_int / emitter_pdf, tex = INVALID + normal = normal, n_g = normal, pos = emit_pos, ray_in = ZERO_V3, beta = emit_int / emitter_pdf, tex = INVALID ) vertex_sampled = True calc_transmittance = fr2light.max() > 0 @@ -378,10 +382,12 @@ def connect_path(self, i: int, j: int, sid: int, tid: int, decomp: int): cam_in_fspace = cam_v.is_in_free_space() lit_in_fspace = lit_v.is_in_free_space() if depth > 0.: # if not occluded - fr_cam = self.eval(int(cam_v.obj_id), cam_v.ray_in, connect_dir, - cam_v.normal, cam_v.is_mi(), cam_in_fspace, TRANSPORT_RAD, cam_v.tex) - fr_lit = self.eval(int(lit_v.obj_id), lit_v.ray_in, -connect_dir, - lit_v.normal, lit_v.is_mi(), lit_in_fspace, TRANSPORT_IMP, lit_v.tex) + cam_vit = cam_v.get_interaction() + lit_vit = lit_v.get_interaction() + fr_cam = self.eval(cam_vit, cam_v.ray_in, connect_dir, + cam_v.is_mi(), cam_in_fspace, TRANSPORT_RAD) + fr_lit = self.eval(lit_vit, lit_v.ray_in, -connect_dir, + lit_v.is_mi(), lit_in_fspace, TRANSPORT_IMP) # Geometry term: two cosine is in fr_xxx, length^{-2} is directly computed here calc_transmittance = fr_cam.max() > 0 and fr_lit.max() > 0 le = cam_v.beta * fr_cam * fr_lit * lit_v.beta / (depth * depth) diff --git a/renderer/vpt.py b/renderer/vpt.py index 409d6a8..c8d66ba 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -15,6 +15,7 @@ from emitters.abtract_source import LightSource from parsers.obj_desc import ObjDescriptor +from sampler.general_sampling import balance_heuristic from rich.console import Console CONSOLE = Console(width = 128) @@ -87,26 +88,26 @@ def track_ray(self, ray, start_p, depth): cur_ray = ray.normalized() acc_depth = 0.0 for _i in range(7): # maximum tracking depth = 7 (corresponding to at most 2 clouds of smoke) - obj_id, normal, min_depth, _p, _u, _v = self.ray_intersect(cur_ray, cur_point, depth) - if obj_id < 0: + it = self.ray_intersect(cur_ray, cur_point, depth) + if it.obj_id < 0: acc_depth += depth * self.world.medium.ior # definitely not in an object if not self.world_scattering: break # nothing is hit, break else: # the world is filled with scattering medium - min_depth = depth + it.min_depth = depth in_free_space = True - obj_id = -1 + it.obj_id = -1 else: - if self.non_null_surface(obj_id): # non-null surface blocks the ray path, break + if self.non_null_surface(it.obj_id): # non-null surface blocks the ray path, break tr.fill(0.0) # travelling time need not to be calculated here since we will abandon this path break - in_free_space = tm.dot(normal, cur_ray) < 0 - acc_depth += min_depth * self.get_ior(obj_id, in_free_space) + in_free_space = tm.dot(it.n_g, cur_ray) < 0 + acc_depth += it.min_depth * self.get_ior(it.obj_id, in_free_space) # invalid medium can be "BRDF" or "transparent medium". Transparent medium has non-null surface, therefore invalid # TODO: I feel something is not right here... - transmittance = self.get_transmittance(obj_id, in_free_space, min_depth) + transmittance = self.get_transmittance(it.obj_id, in_free_space, it.min_depth) tr *= transmittance - cur_point += cur_ray * min_depth - depth -= min_depth + cur_point += cur_ray * it.min_depth + depth -= it.min_depth if depth <= 5e-5: break # reach the target point: break return tr, acc_depth @@ -122,12 +123,13 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int for i, j in self.pixels: in_crop_range = i >= self.start_x and i < self.end_x and j >= self.start_y and j < self.end_y if not self.do_crop or in_crop_range: - # TODO: MIS in VPT is not considered yet (too complex) + # TODO: MIS in VPT (now I have a good understanding for VPT) ray_d = self.pix2ray(i, j) ray_o = self.cam_t - normal = vec3([0, 1, 0]) color = vec3([0, 0, 0]) throughput = vec3([1, 1, 1]) + emission_weight = 1.0 + in_free_space = True bounce = 0 while True: @@ -137,60 +139,73 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int if ti.random(float) > max_value: break else: throughput *= 1. / ti.max(max_value, 1e-7) # unbiased calculation # Step 2: ray intersection - obj_id, normal, min_depth, prim_id, u_coord, v_coord = self.ray_intersect(ray_d, ray_o) - if obj_id < 0: + it = self.ray_intersect(ray_d, ray_o) + if it.obj_id < 0: if not self.world_scattering: break # nothing is hit, break else: # the world is filled with scattering medium min_depth = self.world_bound_time(ray_o, ray_d) in_free_space = True - obj_id = -1 + it.obj_id = -1 else: - in_free_space = tm.dot(normal, ray_d) < 0 + in_free_space = tm.dot(it.n_g, ray_d) < 0 # Step 3: check for mean free path sampling # Calculate mfp, path_beta = transmittance / PDF - is_mi, min_depth, path_beta = self.sample_mfp(obj_id, in_free_space, min_depth) - if obj_id < 0 and not is_mi: break # exiting world bound + is_mi, min_depth, path_beta = self.sample_mfp(it.obj_id, in_free_space, min_depth) + if it.obj_id < 0 and not is_mi: break # exiting world bound hit_point = ray_d * min_depth + ray_o throughput *= path_beta # attenuate first - if not is_mi and not self.non_null_surface(obj_id): + if not is_mi and not self.non_null_surface(it.obj_id): ray_o = hit_point continue - hit_light = -1 if is_mi else self.emitter_id[obj_id] + hit_light = -1 if is_mi else self.emitter_id[it.obj_id] # Step 4: direct component estimation emitter_pdf = 1.0 break_flag = False shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, obj_id, prim_id, u_coord, v_coord) + tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) # direct / emission component evaluation if emitter_valid: - emit_pos, shadow_int, _d, _n = emitter. \ + emit_pos, shadow_int, direct_pdf, _n = emitter. \ sample_hit(self.precom_vec, self.normals, self.obj_info, hit_point) # sample light to_emitter = emit_pos - hit_point emitter_d = to_emitter.norm() light_dir = to_emitter / emitter_d tr, _ = self.track_ray(light_dir, hit_point, emitter_d) shadow_int *= tr - direct_spec = self.eval(obj_id, ray_d, light_dir, normal, is_mi, in_free_space, tex = tex) + direct_spec = self.eval(it, ray_d, light_dir, is_mi, in_free_space) else: # the only situation for being invalid, is when there is only one source and the ray hit the source break_flag = True break - direct_int += direct_spec * shadow_int / emitter_pdf + light_pdf = emitter_pdf * direct_pdf + if ti.static(self.use_mis): # MIS for vpt + mis_w = 1.0 + if not emitter.is_delta_pos(): + bsdf_pdf = 1. + if is_mi: + bsdf_pdf = direct_spec[0] # all elements are phase function value + else: + bsdf_pdf = self.surface_pdf(it, light_dir, ray_d) + mis_w = balance_heuristic(light_pdf, bsdf_pdf) + direct_int += direct_spec * shadow_int * mis_w / emitter_pdf + else: + direct_int += direct_spec * shadow_int / emitter_pdf + if not break_flag: direct_int *= self.inv_num_shadow_ray # Step 5: emission evaluation - ray hitting an area light source emit_int = vec3([0, 0, 0]) if hit_light >= 0: - emit_int = self.src_field[hit_light].eval_le(hit_point - ray_o, normal) + emit_int = self.src_field[hit_light].eval_le(hit_point - ray_o, it.n_g) # Step 6: sample new ray. This should distinguish between surface and medium interactions - ray_d, indirect_spec, ray_pdf = self.sample_new_ray(obj_id, ray_d, normal, is_mi, in_free_space, tex = tex) + ray_d, indirect_spec, ray_pdf = self.sample_new_ray(it, ray_d, is_mi, in_free_space) ray_o = hit_point - color += (direct_int + emit_int) * throughput + color += (direct_int + emit_int * emission_weight) * throughput if not is_mi: if indirect_spec.max() == 0. or ray_pdf == 0.: break throughput *= (indirect_spec / ray_pdf) @@ -198,6 +213,14 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int if bounce >= self.max_bounce: break + if it.obj_id >= 0: # emission MIS for volpath + hit_light = self.emitter_id[it.obj_id] + if ti.static(self.use_mis): + emitter_pdf = 0.0 + if hit_light >= 0 and self.is_delta(it.obj_id) == 0: + emitter_pdf = self.src_field[hit_light].solid_angle_pdf(it, ray_d) + emission_weight = balance_heuristic(ray_pdf, emitter_pdf) + self.color[i, j] += ti.select(ti.math.isnan(color), 0., color) self.pixels[i, j] = self.color[i, j] / self.cnt[None] diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 5eb7bd3..93ab1b4 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -102,10 +102,11 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.has_bump_map = False self.has_roughness_map = False else: - images = prop["packed_texture"] # dict ('albedo': Optional(), 'normal': ...) - for key, image in images.item(): + images = prop["packed_textures"] # dict ('albedo': Optional(), 'normal': ...) + for key, image in images.items(): if image is None: # no image means we don't have this kind of mapping self.__setattr__(f"{key}_img", ti.Vector.field(3, float, (1, 1))) + self.__setattr__(f"has_{key}_map", False) continue tex_h, tex_w, _ = image.shape self.__setattr__(f"has_{key}_map", True) From 7bfeb7dbfbd81fd51969882df1da761302b81325 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Tue, 27 Jun 2023 10:55:23 +0800 Subject: [PATCH 08/18] MIS for vpt worked. BDPT WIP. --- renderer/vpt.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/renderer/vpt.py b/renderer/vpt.py index c8d66ba..5ee8c19 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -143,16 +143,16 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int if it.obj_id < 0: if not self.world_scattering: break # nothing is hit, break else: # the world is filled with scattering medium - min_depth = self.world_bound_time(ray_o, ray_d) + it.min_depth = self.world_bound_time(ray_o, ray_d) in_free_space = True it.obj_id = -1 else: in_free_space = tm.dot(it.n_g, ray_d) < 0 # Step 3: check for mean free path sampling # Calculate mfp, path_beta = transmittance / PDF - is_mi, min_depth, path_beta = self.sample_mfp(it.obj_id, in_free_space, min_depth) + is_mi, it.min_depth, path_beta = self.sample_mfp(it.obj_id, in_free_space, it.min_depth) if it.obj_id < 0 and not is_mi: break # exiting world bound - hit_point = ray_d * min_depth + ray_o + hit_point = ray_d * it.min_depth + ray_o throughput *= path_beta # attenuate first if not is_mi and not self.non_null_surface(it.obj_id): ray_o = hit_point @@ -164,7 +164,8 @@ def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int shadow_int = vec3([0, 0, 0]) direct_int = vec3([0, 0, 0]) direct_spec = vec3([1, 1, 1]) - tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) + direct_pdf = 1. + it.tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) for _j in range(self.num_shadow_ray): # more shadow ray samples emitter, emitter_pdf, emitter_valid, _ei = self.sample_light(hit_light) light_dir = vec3([0, 0, 0]) From 1dfc964217eb35c636a3b58ae1c1ba9970d65346 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Tue, 27 Jun 2023 13:46:08 +0800 Subject: [PATCH 09/18] BDPT is able to use vertex normal. --- README.md | 2 ++ renderer/bdpt.py | 40 +++++++++++++++++++++++++--------------- renderer/path_utils.py | 8 ++++---- requirements.txt | 2 +- tracer/path_tracer.py | 2 +- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 4c6fe04..4c21a0f 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,8 @@ BTW, I am just a starter in CG (ray-tracing stuffs) and Taichi Lang, so there WI ### Rendering Example +Note that the Taichi lang version used on your machine **should not exceed 1.5.0**. Since version 1.6.0 there will be a JIT compilation bug that I am not yet able to locate. This problem will be fixed in the future if my code has something erroneous. + ​ To run the rendering, use: ```shell diff --git a/renderer/bdpt.py b/renderer/bdpt.py index 040ef1f..6c29c6f 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -190,7 +190,7 @@ def generate_eye_path(self, i: int, j: int, max_bnc: int): # Starting vertex assignment, note that camera should be a connectible vertex self.cam_paths[i, j, 0] = Vertex(_type = VERTEX_CAMERA, obj_id = -1, emit_id = -1, bool_bits = BDPT.get_bool(p_delta = True, in_fspace = self.free_space_cam), time = self.init_time, - normal = ZERO_V3, pos = self.cam_t, ray_in = ZERO_V3, beta = vec3([1., 1., 1.]) + n_s = ZERO_V3, n_g = ZERO_V3, pos = self.cam_t, ray_in = ZERO_V3, beta = vec3([1., 1., 1.]) ) return self.random_walk(i, j, max_bnc, self.cam_t, ray_d, pdf_dir, ONES_V3, TRANSPORT_RAD) + 1 @@ -202,7 +202,7 @@ def generate_light_path(self, i: int, j: int, max_bnc: int): vertex_pdf = pdf_pos * emitter_pdf self.light_paths[i, j, 0] = Vertex(_type = VERTEX_EMITTER, obj_id = emitter.obj_ref_id, emit_id = emit_id, bool_bits = emitter.bool_bits, time = emitter.emit_time, pdf_fwd = vertex_pdf, - normal = normal, pos = ray_o, ray_in = ZERO_V3, beta = ret_int + n_s = normal, n_g = normal, pos = ray_o, ray_in = ZERO_V3, beta = ret_int ) vertex_num = 0 if pdf_dir > 0. and ret_int.max() > 0. and vertex_pdf > 0.: # black emitter / inpossible direction @@ -235,7 +235,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: if not self.world_scattering: break # nothing is hit, break else: # the world is filled with scattering medium # TODO: This may not be totally correct, should be double-checked - min_depth = self.world_bound_time(ray_o, ray_d) + it.min_depth = self.world_bound_time(ray_o, ray_d) in_free_space = True it.obj_id = -1 else: @@ -243,14 +243,14 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: # Step 2: check for mean free path sampling # Calculate mfp, path_beta = transmittance / PDF - is_mi, min_depth, path_beta = self.sample_mfp(it.obj_id, in_free_space, min_depth) + is_mi, it.min_depth, path_beta = self.sample_mfp(it.obj_id, in_free_space, it.min_depth) if it.obj_id < 0 and not is_mi: break # exiting world bound throughput *= path_beta # attenuate first if throughput.max() < 5e-5: break - hit_point = ray_d * min_depth + ray_o + hit_point = ray_d * it.min_depth + ray_o hit_light = -1 if is_mi else self.emitter_id[it.obj_id] - acc_time += min_depth * self.get_ior(it.obj_id, in_free_space) + acc_time += it.min_depth * self.get_ior(it.obj_id, in_free_space) # Do not place vertex on null surface (no correct answer about whether it's surface or medium) if not is_mi and not self.non_null_surface(it.obj_id): # surface interaction for null surface should be skipped @@ -263,11 +263,11 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: is_delta = (not is_mi) and self.is_delta(it.obj_id) bool_bits = BDPT.get_bool(d_delta = is_delta, is_area = (hit_light >= 0), in_fspace = in_free_space, is_delta = is_delta) - tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) + it.tex, _vl = self.get_uv_item(self.albedo_map, self.albedo_img, it) vertex_args = {"_type": ti.select(is_mi, VERTEX_MEDIUM, VERTEX_SURFACE), "obj_id": it.obj_id, "emit_id": hit_light, "bool_bits": bool_bits, "pdf_fwd": pdf_fwd, "time": acc_time, "pos": hit_point, - "normal": ti.select(is_mi, ZERO_V3, it.n_s), "n_g": ti.select(is_mi, ZERO_V3, it.n_g), - "ray_in": ray_d, "beta": throughput, "tex": tex + "n_s": ti.select(is_mi, ZERO_V3, it.n_s), "n_g": ti.select(is_mi, ZERO_V3, it.n_g), + "ray_in": ray_d, "beta": throughput, "tex": it.tex } vertex_num += 1 if transport_mode == TRANSPORT_IMP: # Camera path @@ -296,7 +296,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: else: # Step 6: re-evaluate backward PDF pdf_bwd = self.surface_pdf(it, -old_ray_d, -ray_d) - + throughput *= BDPT.correct_shading_normal(it, old_ray_d, ray_d, is_mi, transport_mode) # ray_o is the position of the current vertex, which is used in prev vertex pdf_bwd if transport_mode == TRANSPORT_IMP: # Camera transport mode self.light_paths[i, j, prev_vid].set_pdf_bwd(pdf_bwd, ray_o) @@ -337,7 +337,7 @@ def connect_path(self, i: int, j: int, sid: int, tid: int, decomp: int): bool_bits = BDPT.get_bool(True, in_fspace = self.free_space_cam) sampled_v = Vertex(_type = VERTEX_CAMERA, obj_id = -1, emit_id = -1, bool_bits = bool_bits, time = vertex.time + depth, - normal = self.cam_normal, n_g = self.cam_normal, + n_s = self.cam_normal, n_g = self.cam_normal, pos = self.cam_t, ray_in = ZERO_V3, beta = we / cam_pdf, tex = INVALID ) vertex_sampled = True @@ -365,7 +365,7 @@ def connect_path(self, i: int, j: int, sid: int, tid: int, decomp: int): # Sample hit should also return uv coords sampled_v = Vertex(_type = VERTEX_EMITTER, obj_id = self.get_associated_obj(emit_id), emit_id = emit_id, bool_bits = emitter.bool_bits, time = emitter.emit_time, pdf_fwd = emitter.area_pdf() / float(self.src_num), - normal = normal, n_g = normal, pos = emit_pos, ray_in = ZERO_V3, beta = emit_int / emitter_pdf, tex = INVALID + n_s = normal, n_g = normal, pos = emit_pos, ray_in = ZERO_V3, beta = emit_int / emitter_pdf, tex = INVALID ) vertex_sampled = True calc_transmittance = fr2light.max() > 0 @@ -565,7 +565,8 @@ def pdf_ratio(self, cur: ti.template(), prev_pos, next: ti.template(), prev_null if ray_out_norm > 0.: normed_ray_out = ray_out / ray_out_norm # FIXME: emitter can be inside the Medium (not in the free space), therefore `is_mi` can not only be `cur._type == VERTEX_MEDIUM` - pdf_sa = self.get_pdf(int(cur.obj_id), ray_in, normed_ray_out, cur.normal, cur._type == VERTEX_MEDIUM, is_in_fspace, cur.tex) + cur_vit = cur.get_interaction() + pdf_sa = self.get_pdf(cur_vit, ray_in, normed_ray_out, cur._type == VERTEX_MEDIUM, is_in_fspace) if cur._type != VERTEX_EMITTER: # convert to area measure for the next node pdf_area = next.get_pdf_bwd(pdf_sa, cur.pos) @@ -577,12 +578,21 @@ def pdf_light(self, cur: ti.template(), prev: ti.template()): ray_dir = prev.pos - cur.pos inv_len = 1. / ray_dir.norm() ray_dir *= inv_len - pdf = self.src_field[int(cur.emit_id)].direction_pdf(ray_dir, cur.normal) + pdf = self.src_field[int(cur.emit_id)].direction_pdf(ray_dir, cur.n_g) # use geometric normal for emitters if prev.has_normal(): - pdf *= ti.abs(tm.dot(ray_dir, prev.normal)) + pdf *= ti.abs(tm.dot(ray_dir, prev.n_s)) pdf *= (inv_len * inv_len) return pdf + @staticmethod + @ti.func + def correct_shading_normal(it: ti.template(), incid: vec3, outd: vec3, is_mi, tr_mode: int): + """ Correct shading normal """ + val = 1. + if tr_mode == TRANSPORT_IMP and not is_mi: + val = ti.abs(tm.dot(it.n_s, outd) * tm.dot(it.n_g, incid) / tm.dot(it.n_g, outd) * tm.dot(it.n_s, incid)) + return val + @staticmethod @ti.func def convert_density(pdf: float, diff_vec: vec3, next_nv: vec3, next_mi:int): diff --git a/renderer/path_utils.py b/renderer/path_utils.py index 95f91f8..7897e52 100644 --- a/renderer/path_utils.py +++ b/renderer/path_utils.py @@ -33,7 +33,7 @@ class Vertex: """ backward pdf """ time: float """ hit time (reserved for future uses) """ - normal: vec3 + n_s: vec3 """ hit normal (shading normal) """ n_g: vec3 """ hit normal (geometric normal) """ @@ -57,7 +57,7 @@ def get_pdf_bwd(self, pdf: float, next_point: vec3): inv_norm2 = 1. / diff_vec.norm_sqr() pdf *= inv_norm2 if self.has_normal(): # camera has no normal, for now (pin-hole) - pdf *= ti.abs(tm.dot(self.normal, diff_vec * ti.sqrt(inv_norm2))) + pdf *= ti.abs(tm.dot(self.n_s, diff_vec * ti.sqrt(inv_norm2))) return pdf @ti.func @@ -75,7 +75,7 @@ def is_in_free_space(self): @ti.func def has_normal(self): # Point Source / Area Source / Surface interaction vertex all have a normal - return (self.normal != ZERO_V3).any() + return (self.n_s != ZERO_V3).any() @ti.func def pdf_ratio(self): @@ -101,5 +101,5 @@ def not_delta_source(self): @ti.func def get_interaction(self) -> Interaction: # FIXME: self.normal - return Interaction(obj_id = self.obj_id, n_s = self.normal, n_g = self.n_g, tex = self.tex) + return Interaction(obj_id = self.obj_id, n_s = self.n_s, n_g = self.n_g, tex = self.tex) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 81c331e..ca9453d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -taichi>=1.4.0 +taichi==1.5.0 numpy>=1.23.0 scipy>=1.10.0 matplotlib>=3.6.0 diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 93ab1b4..935cd0e 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -470,7 +470,7 @@ def get_pdf(self, it: ti.template(), incid: vec3, out: vec3, is_mi: int, in_free else: pdf = self.bsdf_field[it.obj_id].medium.eval(incid, out) else: - pdf = self.surface_pdf(it, it.obj_id, out, incid) + pdf = self.surface_pdf(it, out, incid) return pdf @ti.func From cec6a383acd1667a779b1d5365fd1a3e165f271a Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Wed, 28 Jun 2023 00:38:04 +0800 Subject: [PATCH 10/18] WIP: object loading acceleration. --- .vscode/settings.json | 71 +++++++++++++++++++++++++++++++++++++++++++ parsers/xml_parser.py | 8 ++--- render.py | 4 +-- tracer/bvh/bvh.cpp | 65 +++++++++++++++++++++++++++++++++++---- tracer/path_tracer.py | 30 ++++++++++++++++++ 5 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..32770c0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,71 @@ +{ + "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "array": "cpp", + "atomic": "cpp", + "strstream": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "codecvt": "cpp", + "complex": "cpp", + "condition_variable": "cpp", + "cstdint": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "filesystem": "cpp", + "functional": "cpp", + "iterator": "cpp", + "map": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "set": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cfenv": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp", + "bit": "cpp" + } +} \ No newline at end of file diff --git a/parsers/xml_parser.py b/parsers/xml_parser.py index 12bde42..aa4fac3 100644 --- a/parsers/xml_parser.py +++ b/parsers/xml_parser.py @@ -237,15 +237,15 @@ def scene_parsing(directory: str, file: str): roughness is of lower priority - [ ] Speed up python->taichi conversion """ - meshes, area_lut, has_vertex_normal \ + all_objs, area_lut, has_vertex_normal \ = parse_wavefront(directory, shape_nodes, bsdf_dict, emitter_dict, textures) configs = parse_global_sensor(sensor_node) configs['world'] = parse_world(world_node) configs['packed_textures'] = teximgs configs['has_vertex_normal'] = has_vertex_normal emitter_configs = update_emitter_config(emitter_configs, area_lut) - return emitter_configs, meshes, configs + return emitter_configs, all_objs, configs if __name__ == "__main__": - emitter_configs, meshes, configs = scene_parsing("../scenes/", "cbox/complex.xml") - print(emitter_configs, meshes, configs) \ No newline at end of file + emitter_configs, all_objs, configs = scene_parsing("../scenes/", "cbox/complex.xml") + print(emitter_configs, all_objs, configs) \ No newline at end of file diff --git a/render.py b/render.py index f4df3a1..b8cb54f 100644 --- a/render.py +++ b/render.py @@ -67,12 +67,12 @@ def save_check_point(chkpt: dict, opts): ti.init(arch = mapped_arch(opts.arch), kernel_profiler = opts.profile, device_memory_fraction = 0.8, offline_cache = not opts.no_cache, \ default_ip = ti.i32, default_fp = ti.f32, offline_cache_file_path = cache_path, debug = opts.debug) input_folder = os.path.join(opts.input_path, opts.scene) - emitter_configs, meshes, configs = scene_parsing(input_folder, opts.name) # complex_cornell + emitter_configs, all_objs, configs = scene_parsing(input_folder, opts.name) # complex_cornell output_folder = f"{folder_path(opts.output_path)}" output_freq = opts.output_freq if output_freq > 0: output_folder = folder_path(f"{output_folder}{opts.img_name}-{opts.name[:-4]}-{opts.type}/") - rdr: PathTracer = rdr_mapping[opts.type](emitter_configs, meshes, configs) + rdr: PathTracer = rdr_mapping[opts.type](emitter_configs, all_objs, configs) if type(rdr) != BDPT and configs.get('decomposition', 'none').startswith('transient'): CONSOLE.log("[bold yellow] Transient rendering is only supported in BDPT renderer.") diff --git a/tracer/bvh/bvh.cpp b/tracer/bvh/bvh.cpp index 7876882..3835556 100644 --- a/tracer/bvh/bvh.cpp +++ b/tracer/bvh/bvh.cpp @@ -212,9 +212,52 @@ int recursive_linearize(BVHNode* cur_node, std::vector& lin_nodes) { } } -std::tuple bvh_build( +// convert from LinearBVH and LinearNode to numpy for kernel to process +std::tuple, py::array_t, py::array_t, py::array_t> + to_numpy(const std::vector& lin_bvhs, const std::vector& lin_nodes +) { + py::array_t bvh_minmax(lin_bvhs.size() * 6); + py::array_t nodes_minmax(lin_nodes.size() * 6); + py::array_t bvh_info(lin_bvhs.size() * 2); + py::array_t nodes_info(lin_nodes.size() * 3); + // multi-threading, convert std::vector directly to numpy array (flattened) + #pragma omp parallel for num_threads(8) + for (size_t i = 0; i < lin_bvhs.size(); i++) { + const LinearBVH& bvh_ref = lin_bvhs[i]; + float* minmax_ptr = bvh_minmax.mutable_data(6 * i); + int* info_ptr = bvh_info.mutable_data(2 * i); + const float* const mini_ptr = bvh_ref.mini.data(0); + const float* const maxi_ptr = bvh_ref.maxi.data(0); + for (size_t j = 0; j < 3; j++) { + *(minmax_ptr + j) = mini_ptr[j]; + *(minmax_ptr + j + 3) = maxi_ptr[j]; + } + *info_ptr = bvh_ref.obj_idx; + *(info_ptr + 1) = bvh_ref.prim_idx; + } + #pragma omp parallel for num_threads(8) + for (size_t i = 0; i < lin_nodes.size(); i++) { + const LinearNode& node_ref = lin_nodes[i]; + float* minmax_ptr = nodes_minmax.mutable_data(6 * i); + int* info_ptr = nodes_info.mutable_data(3 * i); + const float* const mini_ptr = node_ref.mini.data(0); + const float* const maxi_ptr = node_ref.maxi.data(0); + for (size_t j = 0; j < 3; j++) { + *(minmax_ptr + j) = mini_ptr[j]; + *(minmax_ptr + j + 3) = maxi_ptr[j]; + } + *info_ptr = node_ref.base; + *(info_ptr + 1) = node_ref.prim_cnt; + *(info_ptr + 2) = node_ref.all_offset; + } + // Return the resulting arrays, the older versions can be kept for "educational" purposes + return std::make_tuple(bvh_minmax, nodes_minmax, bvh_info, nodes_info); +} + +std::tuple bvh_build_base( const py::array_t& obj_array, const py::array_t& obj_info, - const py::array_t& world_min, const py::array_t& world_max + const py::array_t& world_min, const py::array_t& world_max, + std::vector& lin_bvhs, std::vector& lin_nodes ) { std::vector meshes; std::vector idx_prs; @@ -224,22 +267,32 @@ std::tuple bvh_build( index_input(obj_info, idx_prs, num_prim); create_bvh_info(meshes, idx_prs, bvh_infos); BVHNode* root_node = bvh_root_start(world_min, world_max, node_num, bvh_infos); - std::vector lin_nodes; recursive_linearize(root_node, lin_nodes); - std::vector lin_bvhs; lin_bvhs.reserve(bvh_infos.size()); for (const BVHInfo& bvh: bvh_infos) { lin_bvhs.emplace_back(bvh); } delete root_node; - return std::make_tuple(py::cast(lin_nodes), py::cast(lin_bvhs)); +} + +std::tuple, py::array_t, py::array_t, py::array_t> + bvh_build( + const py::array_t& obj_array, const py::array_t& obj_info, + const py::array_t& world_min, const py::array_t& world_max +) { + std::vector lin_bvhs; + std::vector lin_nodes; + bvh_build_base(obj_array, obj_info, world_min, world_max, lin_bvhs, lin_nodes); + return to_numpy(lin_bvhs, lin_nodes); + // The old way: + // return std::make_tuple(py::cast(lin_nodes), py::cast(lin_bvhs)); } PYBIND11_MODULE(bvh_cpp, m) { m.doc() = "Build SAH-BVH tree via cpp backend\n"; - m.def("bvh_build", &bvh_build, "Build SAH-BVH tree via cpp backend.\n" + m.def("bvh_build", &bvh_build, "Build SAH-BVH tree via cpp backend (return numpy)\n" "Input: obj_array of shape (N_faces, 3, 3), N_faces corresponds to number of primitives (triangles, spheres)\n" "Input: obj_info of shape (2, N_obj), N_obj corresponds to number of object\n" "Input: world_min: world AABB min vertex\n" diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 935cd0e..d5decfd 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -199,6 +199,33 @@ def prepare_for_bvh(self, objects: List[ObjDescriptor]): primitives.append(primitive) primitives = np.stack(primitives, axis = 0).astype(np.float32) return primitives, obj_info + + def load_primitives( + self, primitives: np.ndarray, indices: np.ndarray, + n_g: np.ndarray, n_s: np.ndarray = None, uvs: np.ndarray = None + ): + """ Load primitives via faster API """ + self.prims.from_numpy(primitives) + # sphere primitives are padded + prim_vecs = np.concatenate([ + primitives[..., 1, :] - primitives[..., 0, :], + primitives[..., 2, :] - primitives[..., 0, :], + primitives[..., 0, :]], axis = -2) + prim_vecs[indices, :2, :] = primitives[indices, :2, :] + self.precom_vec.from_numpy(prim_vecs) + self.normals.from_numpy(n_g) + if n_s is not None and self.has_v_normal: + self.v_normals.from_numpy(n_s) + if uvs is not None: + self.uv_coords.from_numpy(uvs) + + def convert_bvh_info(self): + """ Faster API for BVH python-to-taichi conversion + TODO: Here we actually should modify the output pattern of the bvh pybind module + To directly export the information of different field and store them in a numpy array + then we can use a kernel function to load the information to taichi end + """ + pass def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): # FIXME: Path tracer initialization is too slow @@ -214,6 +241,9 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): cur_id = acc_prim_num + j self.prims[cur_id, 0] = vec3(mesh[0]) self.prims[cur_id, 1] = vec3(mesh[1]) + + # FIXME: use numpy and from numpy to accelerate loading + # BVH might have some difficulty, since there is no function API if mesh.shape[0] > 2: # not a sphere self.prims[cur_id, 2] = vec3(mesh[2]) self.precom_vec[cur_id, 0] = self.prims[cur_id, 1] - self.prims[cur_id, 0] From fa3ff13ba043d2100aee4a8dd7808c68d97fc745 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Wed, 28 Jun 2023 12:17:42 +0800 Subject: [PATCH 11/18] Debug WIP: BVH all black, BDPT stuck --- parsers/obj_loader.py | 9 ++- parsers/xml_parser.py | 49 +++++++++++++--- render.py | 4 +- renderer/bdpt.py | 10 +++- renderer/vanilla_renderer.py | 7 ++- renderer/vpt.py | 7 ++- scene_viz.py | 36 +++++++----- tracer/bvh/bvh.cpp | 12 ++-- tracer/direct_render.py | 19 ++---- tracer/path_tracer.py | 111 ++++++++++++++++------------------- tracer/setup.py | 2 +- tracer/tracer_base.py | 23 +++++++- 12 files changed, 169 insertions(+), 120 deletions(-) diff --git a/parsers/obj_loader.py b/parsers/obj_loader.py index 29d63d0..8711913 100644 --- a/parsers/obj_loader.py +++ b/parsers/obj_loader.py @@ -3,7 +3,7 @@ @author Qianyue He @date 2023.1.19 """ -__all__ = ['extract_obj_info', 'apply_transform', 'calculate_surface_area'] +__all__ = ['extract_obj_info', 'apply_transform', 'calculate_surface_area', 'TRIANGLE_MESH', 'SPHERE'] import numpy as np import pywavefront as pwf @@ -13,6 +13,9 @@ from rich.console import Console CONSOLE = Console(width = 128) +TRIANGLE_MESH = 0 +SPHERE = 1 + # supported_rot_type = ("euler", "quaternion", "angle-axis") def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): @@ -79,12 +82,12 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): def calculate_surface_area(meshes: Arr, _type = 0): area_sum = 0. - if _type == 0: + if _type == TRIANGLE_MESH: for face in meshes: dv1 = face[1] - face[0] dv2 = face[2] - face[0] area_sum += np.linalg.norm(np.cross(dv1, dv2)) / 2. - elif _type == 1: + elif _type == SPHERE: radius = meshes[0, 1, 0] # ellipsoid surface area approximation area_sum = 4. * np.pi * radius ** 2 diff --git a/parsers/xml_parser.py b/parsers/xml_parser.py index aa4fac3..d0c723d 100644 --- a/parsers/xml_parser.py +++ b/parsers/xml_parser.py @@ -7,6 +7,7 @@ """ import os import sys +import numpy as np sys.path.append("..") import xml.etree.ElementTree as xet @@ -46,6 +47,12 @@ level 1 AABB1 (tri1 tri2 tri3) AABB2 (tri4 tri5 tri6) AABB3 (tri4 tri5 tri6) """ +def none_checker(value, prim_num, last_dim = 3): + """ Check whether the value is None. If True, replace the value with a zero array """ + if value is None: + return np.zeros((prim_num, 3, last_dim), dtype = np.float32) + return value + def update_emitter_config(emitter_config: List, area_lut: dict): for i, emitter in enumerate(emitter_config): if i in area_lut: @@ -83,15 +90,21 @@ def parse_wavefront( directory: str, obj_list: List[xet.Element], bsdf_dict: dict, emitter_dict: dict, texture_dict: List[Texture_np]) -> List[Arr]: """ Parsing wavefront obj file (filename) from list of xml nodes """ - all_objs = [] + all_objs = [] + all_prims = [] + all_uvs = [] + all_normals = [] + all_v_norms = [] + indices = [] # indicating whether the current primitive is sphere or not # Some emitters will be attached to objects, to sample the object-attached emitters # We need to calculate surface area of the object mesh first (asuming each triangle has similar area) attached_area_dict = {} has_vertex_normal = False + cum_prim_num = 0 for elem in obj_list: # vns: vertex normals / uvs: uv coordinates vns, uvs, trans_r, trans_t = None, None, None, None # uv_coordinates and transform - obj_type = 0 + obj_type = TRIANGLE_MESH if elem.get("type") == "obj": filepath_child = elem.find("string") # get mesh / geometrical normal / shading normal / uv coords for texture @@ -104,7 +117,7 @@ def parse_wavefront( has_vertex_normal = True else: # CURRENTLY, only sphere is supported meshes, normals = parse_sphere_element(elem) - obj_type = 1 + obj_type = SPHERE ref_childs = elem.findall("ref") bsdf_item = None texture_group = {"albedo": None, "normal": None, "bump": None, "roughness": None} @@ -135,8 +148,28 @@ def parse_wavefront( if bsdf_item is None: raise ValueError("Object should be attached with a BSDF for now since no default one implemented yet.") + prim_num = meshes.shape[0] + if obj_type == SPHERE: # padding to (1, 3, 3) + meshes = np.concatenate((meshes, np.zeros((1, 1, 3), dtype=np.float32)), axis = -2) + indices.append(prim_num, np.int32) + all_prims.append(meshes) + all_normals.append(normals) + all_v_norms.append(none_checker(vns, prim_num)) + all_uvs.append(none_checker(uvs, prim_num, last_dim = 2)) + # TODO: once we have tested the from_numpy loading scheme, we can remove meshes from the object all_objs.append(ObjDescriptor(meshes, normals, bsdf_item, vns, uvs, texture_group, trans_r, trans_t, emit_ref_id, obj_type)) - return all_objs, attached_area_dict, has_vertex_normal + cum_prim_num += prim_num + + if indices: + indices = np.int64(indices) + else: + indices = None + all_uvs = np.concatenate(all_uvs, axis = 0).astype(np.float32) + all_prims = np.concatenate(all_prims, axis = 0).astype(np.float32) + all_normals = np.concatenate(all_normals, axis = 0).astype(np.float32) + all_v_norms = np.concatenate(all_v_norms, axis = 0).astype(np.float32) + array_info = {"primitives": all_prims, "indices": indices, "n_g": all_normals, "n_s": all_v_norms, "uvs": all_uvs} + return array_info, all_objs, attached_area_dict, has_vertex_normal def parse_bxdf(bxdf_list: List[xet.Element]): """ @@ -237,15 +270,15 @@ def scene_parsing(directory: str, file: str): roughness is of lower priority - [ ] Speed up python->taichi conversion """ - all_objs, area_lut, has_vertex_normal \ + array_info, all_objs, area_lut, has_vertex_normal \ = parse_wavefront(directory, shape_nodes, bsdf_dict, emitter_dict, textures) configs = parse_global_sensor(sensor_node) configs['world'] = parse_world(world_node) configs['packed_textures'] = teximgs configs['has_vertex_normal'] = has_vertex_normal emitter_configs = update_emitter_config(emitter_configs, area_lut) - return emitter_configs, all_objs, configs + return emitter_configs, array_info, all_objs, configs if __name__ == "__main__": - emitter_configs, all_objs, configs = scene_parsing("../scenes/", "cbox/complex.xml") - print(emitter_configs, all_objs, configs) \ No newline at end of file + emitter_configs, array_info, all_objs, configs = scene_parsing("../scenes/", "cbox/complex.xml") + print(emitter_configs, array_info.shape, all_objs, configs) \ No newline at end of file diff --git a/render.py b/render.py index b8cb54f..89e8cab 100644 --- a/render.py +++ b/render.py @@ -67,12 +67,12 @@ def save_check_point(chkpt: dict, opts): ti.init(arch = mapped_arch(opts.arch), kernel_profiler = opts.profile, device_memory_fraction = 0.8, offline_cache = not opts.no_cache, \ default_ip = ti.i32, default_fp = ti.f32, offline_cache_file_path = cache_path, debug = opts.debug) input_folder = os.path.join(opts.input_path, opts.scene) - emitter_configs, all_objs, configs = scene_parsing(input_folder, opts.name) # complex_cornell + emitter_configs, array_info, all_objs, configs = scene_parsing(input_folder, opts.name) # complex_cornell output_folder = f"{folder_path(opts.output_path)}" output_freq = opts.output_freq if output_freq > 0: output_folder = folder_path(f"{output_folder}{opts.img_name}-{opts.name[:-4]}-{opts.type}/") - rdr: PathTracer = rdr_mapping[opts.type](emitter_configs, all_objs, configs) + rdr: PathTracer = rdr_mapping[opts.type](emitter_configs, array_info, all_objs, configs) if type(rdr) != BDPT and configs.get('decomposition', 'none').startswith('transient'): CONSOLE.log("[bold yellow] Transient rendering is only supported in BDPT renderer.") diff --git a/renderer/bdpt.py b/renderer/bdpt.py index 6c29c6f..eafb575 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -38,8 +38,11 @@ def block_size(val, max_val = 512): @ti.data_oriented class BDPT(VolumeRenderer): - def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], prop: dict): - super().__init__(emitters, objects, prop) + def __init__(self, + emitters: List[LightSource], array_info: dict, + objects: List[ObjDescriptor], prop: dict + ): + super().__init__(emitters, array_info, objects, prop, bvh_delay = True) decomp_mode = {'transient_cam': TRANSIENT_CAM, 'transient_lit': TRANSIENT_LIT, 'none': STEADY_STATE} decomp_state = decomp_mode[prop.get('decomposition', 'none')] if decomp_mode == TRANSIENT_LIT: @@ -115,6 +118,9 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr raise ValueError("Transient interval must be positive. Otherwise, meaningful or futile.") else: CONSOLE.log(":flashlight: Steady state BDPT rendering") + + # BVH construction is delayed until all fields are constructed + self.bvh_process(array_info, objects, prop) # self.A is the area of the imaging space on z = 1 plane self.A = float(self.w * self.h) * (self.inv_focal * self.inv_focal) diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index e1e1cdf..50be12f 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -23,8 +23,11 @@ class Renderer(PathTracer): """ Renderer Final Class """ - def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], prop: dict): - super().__init__(emitters, objects, prop) + def __init__(self, + emitters: List[LightSource], array_info: dict, + objects: List[ObjDescriptor], prop: dict + ): + super().__init__(emitters, array_info, objects, prop) @ti.kernel def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int, _b: int): diff --git a/renderer/vpt.py b/renderer/vpt.py index 5ee8c19..a2c39c9 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -29,8 +29,11 @@ class VolumeRenderer(PathTracer): """ Volumetric Renderer Class """ - def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], prop: dict): - super().__init__(emitters, objects, prop) + def __init__(self, + emitters: List[LightSource], array_info: dict, + objects: List[ObjDescriptor], prop: dict, bvh_delay: bool = False + ): + super().__init__(emitters, array_info, objects, prop, bvh_delay) self.world_scattering = self.world.medium._type >= 0 @ti.func diff --git a/scene_viz.py b/scene_viz.py index 09fc897..ca8d561 100644 --- a/scene_viz.py +++ b/scene_viz.py @@ -70,8 +70,24 @@ def __init__(self, objects: List[ObjDescriptor], prop: dict): # pos0: start_idx, pos1: number of primitives, pos2: obj_id (being triangle / sphere? Others to be added, like cylinder, etc.) self.obj_info = ti.field(int, (self.num_objects, 3)) + self.load_primitives(**array_info) self.initialze(objects) + def load_primitives( + self, primitives: np.ndarray, indices: np.ndarray, + n_g: np.ndarray, n_s: np.ndarray, uvs: np.ndarray + ): + """ Load primitives via faster API """ + self.prims.from_numpy(primitives) + # sphere primitives are padded + prim_vecs = np.concatenate([ + primitives[..., 1, :] - primitives[..., 0, :], + primitives[..., 2, :] - primitives[..., 0, :], + primitives[..., 0, :]], axis = -2) + prim_vecs[indices, :2, :] = primitives[indices, :2, :] + self.precom_vec.from_numpy(prim_vecs) + self.normals.from_numpy(n_g) + def set_width(self, val: int): self.w[None] = int(val) @@ -94,19 +110,6 @@ def local_to_global(self): def initialze(self, objects: List[ObjDescriptor]): acc_prim_num = 0 for i, obj in enumerate(objects): - for j, (mesh, normal) in enumerate(zip(obj.meshes, obj.normals)): - cur_id = acc_prim_num + j - self.prims[cur_id, 0] = vec3(mesh[0]) - self.prims[cur_id, 1] = vec3(mesh[1]) - if mesh.shape[0] > 2: # not a sphere - self.prims[cur_id, 2] = vec3(mesh[2]) - self.precom_vec[cur_id, 0] = self.prims[cur_id, 1] - self.prims[cur_id, 0] - self.precom_vec[cur_id, 1] = self.prims[cur_id, 2] - self.prims[cur_id, 0] - self.precom_vec[cur_id, 2] = self.prims[cur_id, 0] - else: - self.precom_vec[cur_id, 0] = self.prims[cur_id, 0] - self.precom_vec[cur_id, 1] = self.prims[cur_id, 1] - self.normals[cur_id] = vec3(normal) self.obj_info[i, 0] = acc_prim_num self.obj_info[i, 1] = obj.tri_num self.obj_info[i, 2] = obj.type @@ -163,9 +166,9 @@ def get_rotation(gui, r, p, y): ti.init(arch = ti.vulkan, default_ip = ti.i32, default_fp = ti.f32, offline_cache_file_path = cache_path) vertex_field = ti.Vector.field(3, float, 8) input_folder = os.path.join(options.input_path, options.scene) - _, meshes, configs = scene_parsing(input_folder, options.name) # complex_cornell + _, array_info, all_objs, configs = scene_parsing(input_folder, options.name) # complex_cornell - viz = Visualizer(meshes, configs) + viz = Visualizer(all_objs, configs) init_R = Rot.from_matrix(viz.cam_r[None].to_numpy()).as_euler('zxy', degrees = True) # GGUI initializations @@ -230,4 +233,5 @@ def get_rotation(gui, r, p, y): vertex_field[i] = vec3(pt) canvas.lines(vertex_field, width = 0.002, color = (0., 0.4, 1.0)) window.show() - if window.running == False: break \ No newline at end of file + if window.running == False: break + \ No newline at end of file diff --git a/tracer/bvh/bvh.cpp b/tracer/bvh/bvh.cpp index 3835556..d840c3f 100644 --- a/tracer/bvh/bvh.cpp +++ b/tracer/bvh/bvh.cpp @@ -220,9 +220,7 @@ std::tuple, py::array_t, py::array_t, py::array_t py::array_t nodes_minmax(lin_nodes.size() * 6); py::array_t bvh_info(lin_bvhs.size() * 2); py::array_t nodes_info(lin_nodes.size() * 3); - // multi-threading, convert std::vector directly to numpy array (flattened) - #pragma omp parallel for num_threads(8) - for (size_t i = 0; i < lin_bvhs.size(); i++) { + for (size_t i = 0; i < lin_bvhs.size(); i += 4) { const LinearBVH& bvh_ref = lin_bvhs[i]; float* minmax_ptr = bvh_minmax.mutable_data(6 * i); int* info_ptr = bvh_info.mutable_data(2 * i); @@ -235,8 +233,7 @@ std::tuple, py::array_t, py::array_t, py::array_t *info_ptr = bvh_ref.obj_idx; *(info_ptr + 1) = bvh_ref.prim_idx; } - #pragma omp parallel for num_threads(8) - for (size_t i = 0; i < lin_nodes.size(); i++) { + for (size_t i = 0; i < lin_nodes.size(); i += 4) { const LinearNode& node_ref = lin_nodes[i]; float* minmax_ptr = nodes_minmax.mutable_data(6 * i); int* info_ptr = nodes_info.mutable_data(3 * i); @@ -254,7 +251,7 @@ std::tuple, py::array_t, py::array_t, py::array_t return std::make_tuple(bvh_minmax, nodes_minmax, bvh_info, nodes_info); } -std::tuple bvh_build_base( +void bvh_build_base( const py::array_t& obj_array, const py::array_t& obj_info, const py::array_t& world_min, const py::array_t& world_max, std::vector& lin_bvhs, std::vector& lin_nodes @@ -272,7 +269,9 @@ std::tuple bvh_build_base( for (const BVHInfo& bvh: bvh_infos) { lin_bvhs.emplace_back(bvh); } + printf("Here, base completed.\n"); delete root_node; + printf("Here, root deleted.\n"); } std::tuple, py::array_t, py::array_t, py::array_t> @@ -283,6 +282,7 @@ std::tuple, py::array_t, py::array_t, py::array_t std::vector lin_bvhs; std::vector lin_nodes; bvh_build_base(obj_array, obj_info, world_min, world_max, lin_bvhs, lin_nodes); + printf("BVH returned, to numpy started.\n"); return to_numpy(lin_bvhs, lin_nodes); // The old way: // return std::make_tuple(py::cast(lin_nodes), py::cast(lin_bvhs)); diff --git a/tracer/direct_render.py b/tracer/direct_render.py index e6676c3..1896683 100644 --- a/tracer/direct_render.py +++ b/tracer/direct_render.py @@ -31,7 +31,10 @@ class BlinnPhongTracer(TracerBase): origin + direction * t = u * PA(vec) + v * PB(vec) + P This is a rank-3 matrix linear equation """ - def __init__(self, emitter: PointSource, objects: List[ObjDescriptor], prop: dict): + def __init__(self, + emitter: PointSource, array_info: dict, + objects: List[ObjDescriptor], prop: dict + ): super().__init__(objects, prop) self.emit_int = vec3(emitter.intensity) @@ -40,24 +43,12 @@ def __init__(self, emitter: PointSource, objects: List[ObjDescriptor], prop: dic self.depth_map = ti.field(float, (self.w, self.h)) # output: gray-scale self.norm_map = ti.Vector.field(3, float, (self.w, self.h)) # output: gray-scale + self.load_primitives(**array_info) self.initialze(objects) def initialze(self, objects: List[ObjDescriptor]): acc_prim_num = 0 for i, obj in enumerate(objects): - for j, (mesh, normal) in enumerate(zip(obj.meshes, obj.normals)): - cur_id = acc_prim_num + j - self.prims[cur_id, 0] = vec3(mesh[0]) - self.prims[cur_id, 1] = vec3(mesh[1]) - if mesh.shape[0] > 2: # not a sphere - self.prims[cur_id, 2] = vec3(mesh[2]) - self.precom_vec[cur_id, 0] = self.prims[cur_id, 1] - self.prims[cur_id, 0] - self.precom_vec[cur_id, 1] = self.prims[cur_id, 2] - self.prims[cur_id, 0] - self.precom_vec[cur_id, 2] = self.prims[cur_id, 0] - else: - self.precom_vec[cur_id, 0] = self.prims[cur_id, 0] - self.precom_vec[cur_id, 1] = self.prims[cur_id, 1] - self.normals[cur_id] = vec3(normal) self.obj_info[i, 0] = acc_prim_num self.obj_info[i, 1] = obj.tri_num self.obj_info[i, 2] = obj.type diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index d5decfd..529b5df 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -51,11 +51,14 @@ class PathTracer(TracerBase): Simple Ray tracing using Bary-centric coordinates This tracer can yield result with global illumination effect """ - def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], prop: dict): - super().__init__(objects, prop) - """ - Implement path tracing algorithms first, then we can improve light source / BSDF / participating media + def __init__(self, + emitters: List[LightSource], array_info: dict, + objects: List[ObjDescriptor], prop: dict, bvh_delay: bool = False + ): + """ bvh_delay: since in taichi, field can not be constructed after a kernel is called + therefore, during BDPT we might need to execute bvh_process manually """ + super().__init__(objects, prop) self.clock = TicToc() self.anti_alias = prop['anti_alias'] self.stratified_sample = prop['stratified_sampling'] # whether to use stratified sampling @@ -115,6 +118,7 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr CONSOLE.log(f"Packed texture image tagged '{key}' loaded: ({tex_w}, {tex_h})") CONSOLE.log(f"Path tracer param loading in {self.clock.toc_tic(True):.3f} ms") + self.load_primitives(**array_info) self.initialze(emitters, objects) CONSOLE.log(f"Path tracer initialization in {self.clock.toc(True):.3f} ms") @@ -128,6 +132,10 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr self.w_aabb_min = ti.min(self.cam_t, min_val) - 0.1 self.w_aabb_max = ti.max(self.cam_t, max_val) + 0.1 + if not bvh_delay: + self.bvh_process(array_info, objects, prop) + + def bvh_process(self, array_info: dict, objects: List[ObjDescriptor], prop: dict): if prop.get('accelerator', 'none') == 'bvh': try: from bvh_cpp import bvh_build @@ -136,22 +144,35 @@ def __init__(self, emitters: List[LightSource], objects: List[ObjDescriptor], pr CONSOLE.log("[yellow]:warning: Warning: Fall back to brute force primitive traversal.") else: CONSOLE.log(":rocket: Using SAH-BVH tree accelerator.") - primitives, obj_info = self.prepare_for_bvh(objects) + old_primitives, obj_info = self.prepare_for_bvh(objects) + primitives = array_info["primitives"] self.clock.tic() - py_nodes, py_bvhs = bvh_build(primitives, obj_info, self.w_aabb_min.to_numpy(), self.w_aabb_max.to_numpy()) - CONSOLE.log(f":rocket: BVH construction finished in {self.clock.toc_tic(True):.3f} ms") + print("BVH build started, old: ", old_primitives.shape, ", new: ", primitives.shape) + bvh_minmax, bvh_info, node_minmax, node_info = \ + bvh_build(primitives, obj_info, self.w_aabb_min.to_numpy(), self.w_aabb_max.to_numpy()) + bvh_minmax = bvh_minmax.reshape(-1, 2, 3) + node_minmax = node_minmax.reshape(-1, 2, 3) + bvh_info = bvh_info.reshape(-1, 2) + node_info = node_info.reshape(-1, 3) + CONSOLE.log(f":rocket: BVH construction finished in {self.clock.toc_tic():.4f} s") - self.node_num = len(py_nodes) - self.bvh_num = len(py_bvhs) + self.node_num = node_info.shape[0] + self.bvh_num = bvh_info.shape[0] + self.clock.tic() self.lin_nodes = LinearNode.field() self.lin_bvhs = LinearBVH.field() ti.root.dense(ti.i, self.node_num).place(self.lin_nodes) ti.root.dense(ti.i, self.bvh_num).place(self.lin_bvhs) - export_python_bvh(self.lin_nodes, self.lin_bvhs, py_nodes, py_bvhs) + self.convert_bvh_info(bvh_minmax, bvh_info, node_minmax, node_info) + CONSOLE.log(f":rocket: BVH exported in {self.clock.toc_tic():.4f} s") + + # export_python_bvh(self.lin_nodes, self.lin_bvhs, py_nodes, py_bvhs) CONSOLE.log(f"{self.node_num } nodes and {self.bvh_num} bvh primitives are loaded.") self.__setattr__("ray_intersect", self.ray_intersect_bvh) self.__setattr__("does_intersect", self.does_intersect_bvh) + else: + CONSOLE.log(f":tractor: No accelerator used. Use a BVH accelerator if num prims {self.num_prims} exceeds 128.") def get_check_point(self): """This is a simple checkpoint saver, which can be hacked. @@ -200,32 +221,28 @@ def prepare_for_bvh(self, objects: List[ObjDescriptor]): primitives = np.stack(primitives, axis = 0).astype(np.float32) return primitives, obj_info - def load_primitives( - self, primitives: np.ndarray, indices: np.ndarray, - n_g: np.ndarray, n_s: np.ndarray = None, uvs: np.ndarray = None + @ti.kernel + def convert_bvh_info(self, + bvh_minmax: ti.types.ndarray(), bvh_info: ti.types.ndarray(), + node_minmax: ti.types.ndarray(), node_info: ti.types.ndarray() ): - """ Load primitives via faster API """ - self.prims.from_numpy(primitives) - # sphere primitives are padded - prim_vecs = np.concatenate([ - primitives[..., 1, :] - primitives[..., 0, :], - primitives[..., 2, :] - primitives[..., 0, :], - primitives[..., 0, :]], axis = -2) - prim_vecs[indices, :2, :] = primitives[indices, :2, :] - self.precom_vec.from_numpy(prim_vecs) - self.normals.from_numpy(n_g) - if n_s is not None and self.has_v_normal: - self.v_normals.from_numpy(n_s) - if uvs is not None: - self.uv_coords.from_numpy(uvs) - - def convert_bvh_info(self): """ Faster API for BVH python-to-taichi conversion TODO: Here we actually should modify the output pattern of the bvh pybind module To directly export the information of different field and store them in a numpy array then we can use a kernel function to load the information to taichi end """ - pass + for i in self.lin_bvhs: + self.lin_bvhs[i] = LinearBVH( + mini = vec3([bvh_minmax[i, 0, 0], bvh_minmax[i, 0, 1], bvh_minmax[i, 0, 2]]), + maxi = vec3([bvh_minmax[i, 1, 0], bvh_minmax[i, 1, 1], bvh_minmax[i, 1, 2]]), + obj_idx = bvh_info[i, 0], prim_idx = bvh_info[i, 1], + ) + for i in self.lin_nodes: + self.lin_nodes[i] = LinearNode( + mini = vec3([node_minmax[i, 0, 0], node_minmax[i, 0, 1], node_minmax[i, 0, 2]]), + maxi = vec3([node_minmax[i, 1, 0], node_minmax[i, 1, 1], node_minmax[i, 1, 2]]), + base = node_info[i, 0], prim_cnt = node_info[i, 1], all_offset = node_info[i, 2] + ) def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): # FIXME: Path tracer initialization is too slow @@ -236,36 +253,6 @@ def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): acc_prim_num = 0 for i, obj in enumerate(objects): - prim_num = obj.meshes.shape[0] - for j, (mesh, normal) in tqdm.tqdm(enumerate(zip(obj.meshes, obj.normals)), total = prim_num): - cur_id = acc_prim_num + j - self.prims[cur_id, 0] = vec3(mesh[0]) - self.prims[cur_id, 1] = vec3(mesh[1]) - - # FIXME: use numpy and from numpy to accelerate loading - # BVH might have some difficulty, since there is no function API - if mesh.shape[0] > 2: # not a sphere - self.prims[cur_id, 2] = vec3(mesh[2]) - self.precom_vec[cur_id, 0] = self.prims[cur_id, 1] - self.prims[cur_id, 0] - self.precom_vec[cur_id, 1] = self.prims[cur_id, 2] - self.prims[cur_id, 0] - self.precom_vec[cur_id, 2] = self.prims[cur_id, 0] - else: - self.precom_vec[cur_id, 0] = self.prims[cur_id, 0] - self.precom_vec[cur_id, 1] = self.prims[cur_id, 1] - if obj.vns is not None: # got vertex normal - pass - self.normals[cur_id] = vec3(normal) - if obj.uv_coords is not None: - uv_coord = obj.uv_coords[j] - self.uv_coords[cur_id, 0] = vec2(uv_coord[0]) - self.uv_coords[cur_id, 1] = vec2(uv_coord[1]) - self.uv_coords[cur_id, 2] = vec2(uv_coord[2]) - if obj.vns is not None: - vn = obj.vns[j] - self.v_normals[cur_id, 0] = vec3(vn[0]) - self.v_normals[cur_id, 1] = vec3(vn[1]) - self.v_normals[cur_id, 2] = vec3(vn[2]) - self.obj_info[i, 0] = acc_prim_num self.obj_info[i, 1] = obj.tri_num self.obj_info[i, 2] = obj.type @@ -563,5 +550,5 @@ def summary(self): options = get_options() ti.init(arch = ti.vulkan, kernel_profiler = options.profile, default_ip = ti.int32, default_fp = ti.f32) input_folder = os.path.join(options.input_path, options.scene) - emitter_configs, meshes, configs = scene_parsing(input_folder, options.name) # complex_cornell - pt = PathTracer(emitter_configs, meshes, configs) \ No newline at end of file + emitter_configs, array_info, all_objs, configs = scene_parsing(input_folder, options.name) # complex_cornell + pt = PathTracer(emitter_configs, all_objs, configs) \ No newline at end of file diff --git a/tracer/setup.py b/tracer/setup.py index fbe86ff..ecdae95 100644 --- a/tracer/setup.py +++ b/tracer/setup.py @@ -1,7 +1,7 @@ from pybind11.setup_helpers import Pybind11Extension from setuptools import setup -__version__ = "0.0.1" +__version__ = "0.1.0" cxx_std=11 ext_modules = [ diff --git a/tracer/tracer_base.py b/tracer/tracer_base.py index c3a8717..0511a1f 100644 --- a/tracer/tracer_base.py +++ b/tracer/tracer_base.py @@ -114,6 +114,25 @@ def __repr__(self): def initialze(self, _objects: List[ObjDescriptor]): pass + def load_primitives( + self, primitives: np.ndarray, indices: np.ndarray, + n_g: np.ndarray, n_s: np.ndarray, uvs: np.ndarray + ): + """ Load primitives via faster API """ + self.prims.from_numpy(primitives) + # sphere primitives are padded + prim_vecs = np.stack([ + primitives[..., 1, :] - primitives[..., 0, :], + primitives[..., 2, :] - primitives[..., 0, :], + primitives[..., 0, :]], axis = -2) + if indices is not None: + prim_vecs[indices, :2, :] = primitives[indices, :2, :] + self.precom_vec.from_numpy(prim_vecs) + self.normals.from_numpy(n_g) + self.uv_coords.from_numpy(uvs) + if self.has_v_normal: + self.v_normals.from_numpy(n_s) + @ti.func def pix2ray(self, i, j): """ @@ -268,5 +287,5 @@ def reset(self): if __name__ == "__main__": ti.init() - _, meshes, configs = scene_parsing("../scene/test/", "test.xml") - base = TracerBase(meshes, configs) + _, array_info, all_objs, configs = scene_parsing("../scene/test/", "test.xml") + base = TracerBase(all_objs, configs) From 9773a46f9ad6daf53163c7d86887a8c6da226623 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Wed, 28 Jun 2023 13:26:00 +0800 Subject: [PATCH 12/18] Taichi 1.5 loading acceleration completed. --- parsers/obj_loader.py | 1 - parsers/xml_parser.py | 2 +- scenes/cbox/bunny.xml | 8 ++++---- tracer/bvh/bvh.cpp | 7 ++----- tracer/path_tracer.py | 20 ++++++-------------- utils/tools.py | 2 +- 6 files changed, 14 insertions(+), 26 deletions(-) diff --git a/parsers/obj_loader.py b/parsers/obj_loader.py index 8711913..0776dc5 100644 --- a/parsers/obj_loader.py +++ b/parsers/obj_loader.py @@ -37,7 +37,6 @@ def extract_obj_info(path: str, verbose = True, auto_scale_uv = False): break if material is not None: vert_type = material.vertex_format - print(vert_type) if "T" not in vert_type: if verbose: CONSOLE.log(f"[blue]Attention: Object contains no uv-coordinates for vtype '{vert_type}'") diff --git a/parsers/xml_parser.py b/parsers/xml_parser.py index d0c723d..288619a 100644 --- a/parsers/xml_parser.py +++ b/parsers/xml_parser.py @@ -151,7 +151,7 @@ def parse_wavefront( prim_num = meshes.shape[0] if obj_type == SPHERE: # padding to (1, 3, 3) meshes = np.concatenate((meshes, np.zeros((1, 1, 3), dtype=np.float32)), axis = -2) - indices.append(prim_num, np.int32) + indices.append(cum_prim_num) all_prims.append(meshes) all_normals.append(normals) all_v_norms.append(none_checker(vns, prim_num)) diff --git a/scenes/cbox/bunny.xml b/scenes/cbox/bunny.xml index 91346cd..ab4cf5c 100755 --- a/scenes/cbox/bunny.xml +++ b/scenes/cbox/bunny.xml @@ -11,7 +11,7 @@ - + @@ -159,13 +159,13 @@ - - + - + + diff --git a/tracer/bvh/bvh.cpp b/tracer/bvh/bvh.cpp index d840c3f..55aee80 100644 --- a/tracer/bvh/bvh.cpp +++ b/tracer/bvh/bvh.cpp @@ -220,7 +220,7 @@ std::tuple, py::array_t, py::array_t, py::array_t py::array_t nodes_minmax(lin_nodes.size() * 6); py::array_t bvh_info(lin_bvhs.size() * 2); py::array_t nodes_info(lin_nodes.size() * 3); - for (size_t i = 0; i < lin_bvhs.size(); i += 4) { + for (size_t i = 0; i < lin_bvhs.size(); i++) { const LinearBVH& bvh_ref = lin_bvhs[i]; float* minmax_ptr = bvh_minmax.mutable_data(6 * i); int* info_ptr = bvh_info.mutable_data(2 * i); @@ -233,7 +233,7 @@ std::tuple, py::array_t, py::array_t, py::array_t *info_ptr = bvh_ref.obj_idx; *(info_ptr + 1) = bvh_ref.prim_idx; } - for (size_t i = 0; i < lin_nodes.size(); i += 4) { + for (size_t i = 0; i < lin_nodes.size(); i++) { const LinearNode& node_ref = lin_nodes[i]; float* minmax_ptr = nodes_minmax.mutable_data(6 * i); int* info_ptr = nodes_info.mutable_data(3 * i); @@ -269,9 +269,7 @@ void bvh_build_base( for (const BVHInfo& bvh: bvh_infos) { lin_bvhs.emplace_back(bvh); } - printf("Here, base completed.\n"); delete root_node; - printf("Here, root deleted.\n"); } std::tuple, py::array_t, py::array_t, py::array_t> @@ -282,7 +280,6 @@ std::tuple, py::array_t, py::array_t, py::array_t std::vector lin_bvhs; std::vector lin_nodes; bvh_build_base(obj_array, obj_info, world_min, world_max, lin_bvhs, lin_nodes); - printf("BVH returned, to numpy started.\n"); return to_numpy(lin_bvhs, lin_nodes); // The old way: // return std::make_tuple(py::cast(lin_nodes), py::cast(lin_bvhs)); diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 529b5df..85b9662 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -117,10 +117,10 @@ def __init__(self, self.__getattribute__(f"{key}_img").from_numpy(image) CONSOLE.log(f"Packed texture image tagged '{key}' loaded: ({tex_w}, {tex_h})") - CONSOLE.log(f"Path tracer param loading in {self.clock.toc_tic(True):.3f} ms") + CONSOLE.log(f"Path tracer param loading in {self.clock.toc_tic():.4f} s") self.load_primitives(**array_info) self.initialze(emitters, objects) - CONSOLE.log(f"Path tracer initialization in {self.clock.toc(True):.3f} ms") + CONSOLE.log(f"Path tracer initialization in {self.clock.toc():.4f} s") min_val = vec3([1e3, 1e3, 1e3]) max_val = vec3([-1e3, -1e3, -1e3]) @@ -144,11 +144,10 @@ def bvh_process(self, array_info: dict, objects: List[ObjDescriptor], prop: dict CONSOLE.log("[yellow]:warning: Warning: Fall back to brute force primitive traversal.") else: CONSOLE.log(":rocket: Using SAH-BVH tree accelerator.") - old_primitives, obj_info = self.prepare_for_bvh(objects) + obj_info = self.prepare_for_bvh(objects) primitives = array_info["primitives"] self.clock.tic() - print("BVH build started, old: ", old_primitives.shape, ", new: ", primitives.shape) - bvh_minmax, bvh_info, node_minmax, node_info = \ + bvh_minmax, node_minmax, bvh_info, node_info = \ bvh_build(primitives, obj_info, self.w_aabb_min.to_numpy(), self.w_aabb_max.to_numpy()) bvh_minmax = bvh_minmax.reshape(-1, 2, 3) node_minmax = node_minmax.reshape(-1, 2, 3) @@ -207,19 +206,13 @@ def load_check_point(self, check_point: dict): self.cnt[None] = check_point["counter"] def prepare_for_bvh(self, objects: List[ObjDescriptor]): - primitives = [] obj_info = np.zeros((2, len(objects)), dtype = np.int32) - for i, obj in tqdm.tqdm(enumerate(objects)): + for i, obj in enumerate(objects): # for sphere, it would be (1, 2, 3), for others it would be (n, 3, 3) num_primitive = obj.meshes.shape[0] obj_info[0, i] = num_primitive obj_info[1, i] = obj.type - for primitive in obj.meshes: - if primitive.shape[0] < 3: - primitive = np.vstack((primitive, np.zeros((1, 3), dtype=np.float32))) - primitives.append(primitive) - primitives = np.stack(primitives, axis = 0).astype(np.float32) - return primitives, obj_info + return obj_info @ti.kernel def convert_bvh_info(self, @@ -246,7 +239,6 @@ def convert_bvh_info(self, def initialze(self, emitters: List[LightSource], objects: List[ObjDescriptor]): # FIXME: Path tracer initialization is too slow - self.uv_coords.fill(0) for i, emitter in enumerate(emitters): self.src_field[i] = emitter.export() self.src_field[i].obj_ref_id = -1 diff --git a/utils/tools.py b/utils/tools.py index 726ecd1..cb4581d 100644 --- a/utils/tools.py +++ b/utils/tools.py @@ -32,7 +32,7 @@ def inner_wrapper(*args, **kwargs): start_time = time() ret_val = func(*args, **kwargs) if verbose: - CONSOLE.log(f":hourglass_flowing_sand: Function <{func.__name__}> takes {(time() - start_time) * 1e3:.4f} ms") + CONSOLE.log(f":hourglass_flowing_sand: Function <{func.__name__}> takes {time() - start_time:.4f} s") return ret_val return inner_wrapper return outter_wrapper From 88881ca8486f660561938011b851b0544fa4b721 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Wed, 28 Jun 2023 14:23:10 +0800 Subject: [PATCH 13/18] Version 1.6.0 supported --- README.md | 4 +--- bxdf/bsdf.py | 10 +++++----- requirements.txt | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4c21a0f..0ea4865 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,7 @@ BTW, I am just a starter in CG (ray-tracing stuffs) and Taichi Lang, so there WI ### Rendering Example -Note that the Taichi lang version used on your machine **should not exceed 1.5.0**. Since version 1.6.0 there will be a JIT compilation bug that I am not yet able to locate. This problem will be fixed in the future if my code has something erroneous. - -​ To run the rendering, use: +​To run the rendering, use: ```shell # For bidirectional path tracer diff --git a/bxdf/bsdf.py b/bxdf/bsdf.py index 67ac375..d362c18 100644 --- a/bxdf/bsdf.py +++ b/bxdf/bsdf.py @@ -74,7 +74,7 @@ class BSDF: # ========================= Deterministic Refraction ========================= @ti.func - def sample_det_refraction(self, it: ti.template(), incid: vec3, medium, mode): + def sample_det_refraction(self, it: ti.template(), incid: vec3, medium: ti.template(), mode): """ Deterministic refraction sampling - Surface reflection is pure mirror specular \\ other (Medium) could be incident medium or refraction medium, depending on \\ @@ -105,7 +105,7 @@ def sample_det_refraction(self, it: ti.template(), incid: vec3, medium, mode): return ret_dir, ret_int * ret_pdf, ret_pdf @ti.func - def eval_det_refraction(self, it: ti.template(), ray_in: vec3, ray_out: vec3, medium, mode): + def eval_det_refraction(self, it: ti.template(), ray_in: vec3, ray_out: vec3, medium: ti.template(), mode): dot_out = tm.dot(ray_out, it.n_s) entering_this = dot_out < 0 # notice that eval uses ray_out while sampling uses ray_in, therefore nr & ni have different order @@ -136,7 +136,7 @@ def eval_det_refraction(self, it: ti.template(), ray_in: vec3, ray_out: vec3, me # ========================= General operations ========================= @ti.func - def get_pdf(self, it: ti.template(), outdir: vec3, incid: vec3, medium): + def get_pdf(self, it: ti.template(), outdir: vec3, incid: vec3, medium: ti.template()): pdf = 0. if self._type == -1: pdf = ti.select(tm.dot(incid, outdir) > 1 - 5e-5, 1., 0.) @@ -165,14 +165,14 @@ def is_non_null(self): # null surface is -1 # ========================= Surface interactions ============================ @ti.func - def eval_surf(self, it: ti.template(), incid: vec3, out: vec3, medium, mode) -> vec3: + def eval_surf(self, it: ti.template(), incid: vec3, out: vec3, medium: ti.template(), mode) -> vec3: ret_spec = vec3([0, 0, 0]) if self._type == 0: ret_spec = self.eval_det_refraction(it, incid, out, medium, mode) return ret_spec @ti.func - def sample_surf_rays(self, it: ti.template(), incid: vec3, medium, mode): + def sample_surf_rays(self, it: ti.template(), incid: vec3, medium: ti.template(), mode): ret_dir = vec3([0, 0, 0]) ret_spec = vec3([0, 0, 0]) pdf = 0.0 diff --git a/requirements.txt b/requirements.txt index ca9453d..81c331e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -taichi==1.5.0 +taichi>=1.4.0 numpy>=1.23.0 scipy>=1.10.0 matplotlib>=3.6.0 From 5e676bf75639a342a2b6be7bf0d19f8f9a760ced Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Wed, 28 Jun 2023 20:36:24 +0800 Subject: [PATCH 14/18] miscellaneous modifications and runtime acceleration --- bxdf/brdf.py | 2 +- la/cam_transform.py | 2 +- render.py | 6 +++- renderer/bdpt.py | 57 ++++++++++++------------------------ renderer/vanilla_renderer.py | 1 + renderer/vpt.py | 3 +- tracer/path_tracer.py | 5 ++-- 7 files changed, 30 insertions(+), 46 deletions(-) diff --git a/bxdf/brdf.py b/bxdf/brdf.py index dcea7dd..9bf08e0 100644 --- a/bxdf/brdf.py +++ b/bxdf/brdf.py @@ -185,7 +185,7 @@ def fresnel_blend_dir(self, incid: vec3, half: vec3, normal: vec3, power_coeff: @ti.func def fresnel_cos2_sin2(self, half_vec: vec3, normal: vec3, R: mat3, dot_half: float): - transed_x = (R @ vec3([1, 0, 0])).normalized() + transed_x = (R @ vec3([1, 0, 0])) cos_phi2 = tm.dot(transed_x, (half_vec - dot_half * normal).normalized()) ** 2 # azimuth angle of half vector return cos_phi2, 1. - cos_phi2 diff --git a/la/cam_transform.py b/la/cam_transform.py index 7267846..26c6c62 100644 --- a/la/cam_transform.py +++ b/la/cam_transform.py @@ -69,7 +69,7 @@ def rotation_between(fixed: vec3, target: vec3) -> mat3: @ti.func def delocalize_rotate(anchor: vec3, local_dir: vec3): R = rotation_between(vec3([0, 1, 0]), anchor) - return (R @ local_dir).normalized(), R + return R @ local_dir, R @ti.func def world_frame(local_anchor, global_anchor, local_dir): diff --git a/render.py b/render.py index 89e8cab..6d59d40 100644 --- a/render.py +++ b/render.py @@ -151,7 +151,11 @@ def save_check_point(chkpt: dict, opts): ti.tools.imwrite(image, f"{output_folder}img_{iter_cnt:05d}.{opts.img_ext}") rdr.summary() if opts.profile: - ti.profiler.print_kernel_profiler_info() + CONSOLE.rule() + ti.profiler.print_kernel_profiler_info('trace') + CONSOLE.rule() + ti.profiler.print_scoped_profiler_info() + CONSOLE.rule() ti.profiler.memory_profiler.print_memory_profiler_info() image = apply_watermark(rdr, opts.normalize, True, not opts.no_watermark) save_figure = not opts.no_save_fig diff --git a/renderer/bdpt.py b/renderer/bdpt.py index eafb575..650301e 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -29,13 +29,6 @@ T_MAX_BOUNCE = 400 MAX_SAMPLE_CNT = 512 -def block_size(val, max_val = 512): - if val > max_val or val == 0: return max_val - if val % 32 == 0 or (val & (val-1) == 0): return val - cand1 = val - val % 32 - cand2 = 1 << int(log2(val)) - return cand1 if cand1 >= cand2 else cand2 - @ti.data_oriented class BDPT(VolumeRenderer): def __init__(self, @@ -58,8 +51,6 @@ def __init__(self, self.time_cnts = ti.field(ti.i32) self.time_bins = ti.Vector.field(3, float) - self.vertex_cnts = ti.field(ti.i32) - if self.do_crop: # Memory conserving implementation self.path_nodes = ti.root.dense(ti.ij, (self.crop_rx << 1, self.crop_ry << 1)) @@ -83,9 +74,7 @@ def __init__(self, self.lit_bitmask = self.path_nodes.dense(ti.k, max_bounce_used + 1) self.cam_bitmask.place(self.cam_paths, offset = offsets) self.lit_bitmask.place(self.light_paths, offset = offsets) - self.path_nodes.dense(ti.k, 2).place(self.vertex_cnts, offset = offsets) self.path_nodes.place(self.crop_range, offset = (offsets[:2])) - self.conn_path_block_size = block_size(self.max_bounce + 1, 256) # ti.profiler.memory_profiler.print_memory_profiler_info() @@ -138,32 +127,24 @@ def copy_average(self, time_idx: int): @ti.kernel def render(self, t_start: int, t_end: int, s_start: int, s_end: int, max_bnc: int, max_depth: int): - self.cnt[None] += 1 + cnt = ti.atomic_add(self.cnt[None], 1) + 1 decomp = self.decomp[None] min_time = self.min_time[None] max_time = self.max_time[None] interval = self.interval[None] - ti.loop_config(parallelize = 8) - for i, j, k in self.vertex_cnts: - in_crop_range = i >= self.start_x and i < self.end_x and j >= self.start_y and j < self.end_y - if in_crop_range: - if k == 1: - self.vertex_cnts[i, j, 1] = ti.min(self.generate_light_path(i, j, max_bnc) + 1, s_end) # k == 1 - else: - self.vertex_cnts[i, j, 0] = ti.min(self.generate_eye_path(i, j, max_bnc) + 1, t_end) # k == 0 - ti.block_local(self.time_cnts) ti.block_local(self.time_bins) - ti.block_local(self.cam_paths) - ti.block_local(self.light_paths) - ti.loop_config(parallelize = 8, block_dim = self.conn_path_block_size) - for i, j, t in self.cam_paths: + ti.loop_config(parallelize = 8, block_dim = 512) + for i, j in self.pixels: in_crop_range = i >= self.start_x and i < self.end_x and j >= self.start_y and j < self.end_y + local_color = ZERO_V3 if in_crop_range: - t_end_i = self.vertex_cnts[i, j, 0] - s_end_i = self.vertex_cnts[i, j, 1] - if t >= t_start and t < t_end_i: + cam_vnum = self.generate_eye_path(i, j, max_bnc) + 1 + lit_vnum = self.generate_light_path(i, j, max_bnc) + 1 + s_end_i = ti.min(lit_vnum, s_end) + t_end_i = ti.min(cam_vnum, t_end) + for t in range(t_start, t_end_i): for s in range(s_start, s_end_i): depth = s + t - 2 if (s == 1 and t == 1) or depth < 0 or depth > max_depth: @@ -176,13 +157,15 @@ def render(self, t_start: int, t_end: int, s_start: int, s_end: int, max_bnc: in id_j = j if t == 1 and raster_p.min() >= 0: # non-local contribution id_i, id_j = raster_p # splat samples can only contribute in cropping range + self.color[id_i, id_j] += color + else: + local_color += color if decomp >= TRANSIENT_CAM and path_time < max_time and path_time > min_time: time_idx = int((path_time - min_time) / interval) self.time_bins[id_i, id_j, time_idx] += color # time_bins and cnts have offset self.time_cnts[id_i, id_j, time_idx] += 1 - self.color[id_i, id_j] += color - for i, j in self.pixels: - self.pixels[i, j] = self.color[i, j] / self.cnt[None] + self.color[i, j] += local_color + self.pixels[i, j] = self.color[i, j] / cnt def reset(self): """ Resetting path vertex container """ @@ -192,7 +175,7 @@ def reset(self): def generate_eye_path(self, i: int, j: int, max_bnc: int): ray_d = self.pix2ray(i, j) dot_ray = tm.dot(ray_d, self.cam_normal) - _, pdf_dir = self.pdf_camera(dot_ray) + pdf_dir = self.pdf_camera(dot_ray) # Starting vertex assignment, note that camera should be a connectible vertex self.cam_paths[i, j, 0] = Vertex(_type = VERTEX_CAMERA, obj_id = -1, emit_id = -1, bool_bits = BDPT.get_bool(p_delta = True, in_fspace = self.free_space_cam), time = self.init_time, @@ -538,14 +521,10 @@ def pdf_camera(self, dot_normal: float): Implementation see reference: PBR-Book chapter 16-1, equation 16.2 https://www.pbr-book.org/3ed-2018/Light_Transport_III_Bidirectional_Methods/The_Path-Space_Measurement_Equation#eq:importance-sa """ - pdf_pos = 1. - pdf_dir = 1. + pdf_dir = 0. if dot_normal > 0.: # No need to rasterize again pdf_dir /= (self.A * ti.pow(dot_normal, 3)) - else: - pdf_pos = 0. - pdf_dir = 0. - return pdf_pos, pdf_dir + return pdf_dir @ti.func def pdf_ratio(self, cur: ti.template(), prev_pos, next: ti.template(), prev_null = False): @@ -562,7 +541,7 @@ def pdf_ratio(self, cur: ti.template(), prev_pos, next: ti.template(), prev_null elif cur._type == VERTEX_CAMERA: ray_norm = ray_out.norm() if ray_norm > 0: - _pp, pdf_sa = self.pdf_camera(ti.abs(tm.dot(self.cam_normal, ray_out / ray_norm))) + pdf_sa = self.pdf_camera(ti.abs(tm.dot(self.cam_normal, ray_out / ray_norm))) else: is_in_fspace = cur.is_in_free_space() diff --git a/renderer/vanilla_renderer.py b/renderer/vanilla_renderer.py index 50be12f..497b2fa 100644 --- a/renderer/vanilla_renderer.py +++ b/renderer/vanilla_renderer.py @@ -32,6 +32,7 @@ def __init__(self, @ti.kernel def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int, _b: int): self.cnt[None] += 1 + ti.loop_config(parallelize = 8, block_dim = 512) for i, j in self.pixels: in_crop_range = i >= self.start_x and i < self.end_x and j >= self.start_y and j < self.end_y if not self.do_crop or in_crop_range: diff --git a/renderer/vpt.py b/renderer/vpt.py index a2c39c9..280eca3 100644 --- a/renderer/vpt.py +++ b/renderer/vpt.py @@ -88,7 +88,7 @@ def track_ray(self, ray, start_p, depth): tr = vec3([1., 1., 1.]) in_free_space = True cur_point = start_p - cur_ray = ray.normalized() + cur_ray = ray acc_depth = 0.0 for _i in range(7): # maximum tracking depth = 7 (corresponding to at most 2 clouds of smoke) it = self.ray_intersect(cur_ray, cur_point, depth) @@ -123,6 +123,7 @@ def world_bound_time(self, ray_o, ray_d): @ti.kernel def render(self, _t_start: int, _t_end: int, _s_start: int, _s_end: int, _a: int, _b: int): self.cnt[None] += 1 + ti.loop_config(parallelize = 8, block_dim = 512) for i, j in self.pixels: in_crop_range = i >= self.start_x and i < self.end_x and j >= self.start_y and j < self.end_y if not self.do_crop or in_crop_range: diff --git a/tracer/path_tracer.py b/tracer/path_tracer.py index 85b9662..8dd174a 100644 --- a/tracer/path_tracer.py +++ b/tracer/path_tracer.py @@ -295,7 +295,7 @@ def process_ns(self, it: ti.template()): normal, n_valid = self.get_uv_item(self.normal_map, self.normal_img, it) if n_valid: R = rotation_between(vec3([0, 1, 0]), it.n_g) - it.n_s = (R @ normal).normalized() + it.n_s = R @ normal if ti.static(self.has_bump_map): delta_n, d_valid = self.get_uv_item(self.bump_map, self.bump_img, it) if d_valid: @@ -327,8 +327,7 @@ def bvh_intersect(self, bvh_id, ray, start_p): mat = ti.Matrix.cols([v1, v2, -ray]).inverse() u, v, t = mat @ (start_p - p1) # u, v as barycentric coordinates should be returned - if u >= 0 and v >= 0 and u + v <= 1.0: - ray_t = t + ray_t = ti.select(u >= 0 and v >= 0 and u + v <= 1.0, t, ray_t) return ray_t, obj_idx, prim_idx, is_sphere, u, v @ti.func From 479c40e57beae925a480b8be780bb827b84e18f4 Mon Sep 17 00:00:00 2001 From: Enigmatisms <984041003@qq.com> Date: Thu, 29 Jun 2023 00:46:51 +0800 Subject: [PATCH 15/18] Venus scene bump map tested. --- bxdf/texture.py | 4 ++ render.py | 2 +- renderer/bdpt.py | 1 + scenes/cbox/venus.xml | 91 +++++++++++++++++++++++++++++++++++++------ 4 files changed, 86 insertions(+), 12 deletions(-) diff --git a/bxdf/texture.py b/bxdf/texture.py index dec0298..4c1291d 100644 --- a/bxdf/texture.py +++ b/bxdf/texture.py @@ -35,6 +35,7 @@ class Texture_np: MODE_IMAGE = 0 MODE_CHECKER = 1 def __init__(self, elem: xet.Element, max_size = 2048) -> None: + self.tag = elem.get("tag", "albedo") self.max_size = max_size self.id = elem.get("id") self.type = elem.get("type") @@ -71,6 +72,9 @@ def __init__(self, elem: xet.Element, max_size = 2048) -> None: self.h = min(self.h, max_size) texture_img = cv.resize(texture_img, (self.w, self.h)) self.texture_img = texture_img.astype(np.float32) / 255. + if self.tag == "bump": + # since normally, the up-axis for bump map texture is z, but for AdaPT, the axis should be y + self.texture_img[..., [1, 2]] = self.texture_img[..., [2, 1]] float_nodes = elem.findall("float") for float_n in float_nodes: name = float_n.get("name") diff --git a/render.py b/render.py index 6d59d40..36b3e51 100644 --- a/render.py +++ b/render.py @@ -64,7 +64,7 @@ def save_check_point(chkpt: dict, opts): if __name__ == "__main__": opts = get_options() cache_path = folder_path(f"./cached/{opts.scene}", f"Cache path for scene {opts.scene} not found. JIT compilation might take some time (~30s)...") - ti.init(arch = mapped_arch(opts.arch), kernel_profiler = opts.profile, device_memory_fraction = 0.8, offline_cache = not opts.no_cache, \ + ti.init(arch = mapped_arch(opts.arch), kernel_profiler = opts.profile, device_memory_fraction = 0.9, offline_cache = not opts.no_cache, \ default_ip = ti.i32, default_fp = ti.f32, offline_cache_file_path = cache_path, debug = opts.debug) input_folder = os.path.join(opts.input_path, opts.scene) emitter_configs, array_info, all_objs, configs = scene_parsing(input_folder, opts.name) # complex_cornell diff --git a/renderer/bdpt.py b/renderer/bdpt.py index 650301e..c859435 100644 --- a/renderer/bdpt.py +++ b/renderer/bdpt.py @@ -219,6 +219,7 @@ def random_walk(self, i: int, j: int, max_bnc: int, init_ray_o, init_ray_d, pdf: while True: # Step 1: ray intersection it = self.ray_intersect(ray_d, ray_o) + self.process_ns(it) # (possibly) get normal map / bump map if it.obj_id < 0: if not self.world_scattering: break # nothing is hit, break diff --git a/scenes/cbox/venus.xml b/scenes/cbox/venus.xml index b035c00..9bf87cc 100755 --- a/scenes/cbox/venus.xml +++ b/scenes/cbox/venus.xml @@ -10,8 +10,7 @@ - - + @@ -44,43 +43,113 @@ + + + + + + - + - + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5f4b05a042ae5f902afe44c53137331aee1f810c Mon Sep 17 00:00:00 2001 From: hqyswife <126778364+hqyswife@users.noreply.github.com> Date: Thu, 29 Jun 2023 01:07:37 +0800 Subject: [PATCH 16/18] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0ea4865..f73ae39 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Bunny scenes are not uploaded in the repo (90k+ primitives). ##### Console output -Powered by rich console. Note that there is a speed bottle-neck for loading scene objects (see PR #16) +Powered by rich console. Note that the loading speed bottleneck (in the figure) no longer exist after [PR #19](https://github.com/Enigmatisms/AdaPT/pull/19) ! ![Screenshot from 2023-05-31 12-36-59](https://github.com/Enigmatisms/AdaPT/assets/46109954/963448af-da1b-422d-bcf7-e44aa4808973) @@ -53,7 +53,8 @@ Here are the features I currently implemented and support: - A **unidirectional / bidirectional Monte-Carlo MIS path tracer**: supports as many bounce times as you wish, and the rendering process is based on Taichi Lang, therefore it can be very fast (not on the first run, the first run of a scene might take a long time due to taichi function inlining, especially for BDPT). The figures displayed above can be rendered within 15-20s (with cuda-backend, GPU supported). The rendering result is displayed incrementally, or maximum iteration number can be pre-set. - **Volumetric path tracer** that supports uni/bidirectional path tracing in both bounded and unbounded condition - A **transient renderer** with which you can visualize the propagation of the global radiance. -- Texture packing and texture mapping, see `scenes/bunny.xml` for an configuration example. +- Texture packing and texture mapping, see `scenes/bunny.xml` for an configuration example. We support bump map / normal map / roughness map (this is not tested) for now. +- Shading normal is supported for a smooth appearance. - Rendering checkpointing and [rich](https://github.com/Textualize/rich) console pannel support. - Ray tracing accelerating structure, for now, we only support `BVH`. `KD-tree` will be implemented in the future. - Global / indirect illumination & Ability to handle simple caustics From 45771dfa364dbb9ab310008ca24525292032a3af Mon Sep 17 00:00:00 2001 From: hqyswife <126778364+hqyswife@users.noreply.github.com> Date: Thu, 29 Jun 2023 01:08:24 +0800 Subject: [PATCH 17/18] Delete flat-ball.obj --- scenes/meshes/cornell/flat-ball.obj | 2535 --------------------------- 1 file changed, 2535 deletions(-) delete mode 100644 scenes/meshes/cornell/flat-ball.obj diff --git a/scenes/meshes/cornell/flat-ball.obj b/scenes/meshes/cornell/flat-ball.obj deleted file mode 100644 index 9355b72..0000000 --- a/scenes/meshes/cornell/flat-ball.obj +++ /dev/null @@ -1,2535 +0,0 @@ -# Blender 3.5.1 -# www.blender.org -o Sphere.001 -v 4.018694 4.097396 2.700003 -v 4.018694 3.775584 2.378191 -v 4.018694 3.355116 2.204028 -v 4.018694 3.127560 2.181615 -v 4.018694 2.900005 2.204028 -v 4.018694 2.479537 2.378191 -v 4.063088 4.271559 3.124843 -v 4.105776 4.205184 2.910237 -v 4.145117 4.097396 2.712455 -v 4.179600 3.952338 2.539097 -v 4.207900 3.775584 2.396826 -v 4.228928 3.573927 2.291109 -v 4.241877 3.355116 2.226009 -v 4.246249 3.127560 2.204028 -v 4.241877 2.900005 2.226009 -v 4.228928 2.681194 2.291109 -v 4.207900 2.479537 2.396826 -v 4.179600 2.302783 2.539097 -v 4.145117 2.157725 2.712455 -v 4.105776 2.049937 2.910237 -v 4.063088 1.983562 3.124843 -v 4.105776 4.271559 3.137792 -v 4.189511 4.205184 2.935638 -v 4.266682 4.097396 2.749331 -v 4.334322 3.952338 2.586031 -v 4.389834 3.775584 2.452015 -v 4.431082 3.573927 2.352432 -v 4.456483 3.355116 2.291109 -v 4.465060 3.127560 2.270403 -v 4.456483 2.900005 2.291109 -v 4.431082 2.681194 2.352432 -v 4.389834 2.479537 2.452015 -v 4.334322 2.302783 2.586031 -v 4.266682 2.157725 2.749331 -v 4.189511 2.049937 2.935638 -v 4.105776 1.983562 3.137792 -v 4.145117 4.271559 3.158821 -v 4.266682 4.205184 2.976886 -v 4.378716 4.097396 2.809215 -v 4.476915 3.952338 2.662249 -v 4.557506 3.775584 2.541638 -v 4.617389 3.573927 2.452015 -v 4.654265 3.355116 2.396826 -v 4.666717 3.127560 2.378191 -v 4.654265 2.900005 2.396826 -v 4.617389 2.681194 2.452015 -v 4.557506 2.479537 2.541638 -v 4.476915 2.302783 2.662249 -v 4.378716 2.157725 2.809215 -v 4.266682 2.049937 2.976886 -v 4.145117 1.983562 3.158821 -v 4.179600 4.271559 3.187120 -v 4.334322 4.205184 3.032398 -v 4.476915 4.097396 2.889805 -v 4.601900 3.952338 2.764821 -v 4.704471 3.775584 2.662249 -v 4.780688 3.573927 2.586031 -v 4.827623 3.355116 2.539097 -v 4.843471 3.127560 2.523249 -v 4.827623 2.900005 2.539097 -v 4.780688 2.681194 2.586031 -v 4.704471 2.479537 2.662249 -v 4.601900 2.302783 2.764821 -v 4.476915 2.157725 2.889805 -v 4.334322 2.049937 3.032398 -v 4.179600 1.983562 3.187120 -v 4.207900 4.271559 3.221603 -v 4.389834 4.205184 3.100039 -v 4.557506 4.097396 2.988004 -v 4.704471 3.952338 2.889805 -v 4.825082 3.775584 2.809215 -v 4.914705 3.573927 2.749331 -v 4.969894 3.355116 2.712455 -v 4.988529 3.127560 2.700003 -v 4.969894 2.900005 2.712455 -v 4.914705 2.681194 2.749331 -v 4.825082 2.479537 2.809215 -v 4.704471 2.302783 2.889805 -v 4.557506 2.157725 2.988004 -v 4.389834 2.049937 3.100039 -v 4.207900 1.983562 3.221603 -v 4.018694 4.293972 3.348026 -v 4.228928 4.271559 3.260945 -v 4.431082 4.205184 3.177209 -v 4.617389 4.097396 3.100039 -v 4.780689 3.952338 3.032398 -v 4.914705 3.775584 2.976887 -v 5.014288 3.573927 2.935638 -v 5.075611 3.355116 2.910237 -v 5.096317 3.127560 2.901660 -v 5.075611 2.900005 2.910237 -v 5.014288 2.681194 2.935638 -v 4.914705 2.479537 2.976887 -v 4.780689 2.302783 3.032398 -v 4.617389 2.157725 3.100039 -v 4.431082 2.049937 3.177209 -v 4.228928 1.983562 3.260945 -v 4.241877 4.271559 3.303632 -v 4.456483 4.205184 3.260945 -v 4.654265 4.097396 3.221603 -v 4.827623 3.952338 3.187120 -v 4.969894 3.775584 3.158821 -v 5.075611 3.573927 3.137792 -v 5.140711 3.355116 3.124843 -v 5.162693 3.127560 3.120471 -v 5.140711 2.900005 3.124843 -v 5.075611 2.681194 3.137792 -v 4.969894 2.479537 3.158821 -v 4.827623 2.302783 3.187120 -v 4.654265 2.157725 3.221603 -v 4.456483 2.049937 3.260945 -v 4.241877 1.983562 3.303632 -v 4.246249 4.271559 3.348026 -v 4.465060 4.205184 3.348026 -v 4.666717 4.097396 3.348026 -v 4.843471 3.952338 3.348026 -v 4.988529 3.775584 3.348026 -v 5.096317 3.573927 3.348026 -v 5.162693 3.355116 3.348026 -v 5.185104 3.127560 3.348027 -v 5.162693 2.900005 3.348026 -v 5.096317 2.681194 3.348026 -v 4.988529 2.479537 3.348026 -v 4.843471 2.302783 3.348026 -v 4.666717 2.157725 3.348026 -v 4.465060 2.049937 3.348026 -v 4.246249 1.983562 3.348026 -v 4.241877 4.271559 3.392420 -v 4.456483 4.205184 3.435108 -v 4.654265 4.097396 3.474449 -v 4.827623 3.952338 3.508932 -v 4.969894 3.775584 3.537232 -v 5.075611 3.573927 3.558260 -v 5.140711 3.355116 3.571209 -v 5.162692 3.127560 3.575582 -v 5.140711 2.900005 3.571209 -v 5.075611 2.681194 3.558260 -v 4.969894 2.479537 3.537232 -v 4.827623 2.302783 3.508932 -v 4.654265 2.157725 3.474449 -v 4.456483 2.049937 3.435108 -v 4.241877 1.983562 3.392420 -v 4.228928 4.271559 3.435108 -v 4.431082 4.205184 3.518843 -v 4.617389 4.097396 3.596014 -v 4.780688 3.952338 3.663655 -v 4.914705 3.775584 3.719166 -v 5.014288 3.573927 3.760415 -v 5.075611 3.355116 3.785816 -v 5.096317 3.127560 3.794393 -v 5.075611 2.900005 3.785816 -v 5.014288 2.681194 3.760415 -v 4.914705 2.479537 3.719166 -v 4.780688 2.302783 3.663655 -v 4.617389 2.157725 3.596014 -v 4.431082 2.049937 3.518843 -v 4.228928 1.983562 3.435108 -v 4.207899 4.271559 3.474449 -v 4.389834 4.205184 3.596014 -v 4.557506 4.097396 3.708049 -v 4.704471 3.952338 3.806248 -v 4.825082 3.775584 3.886838 -v 4.914705 3.573927 3.946722 -v 4.969894 3.355116 3.983598 -v 4.988529 3.127560 3.996049 -v 4.969894 2.900005 3.983598 -v 4.914705 2.681194 3.946722 -v 4.825082 2.479537 3.886838 -v 4.704471 2.302783 3.806248 -v 4.557506 2.157725 3.708049 -v 4.389834 2.049937 3.596014 -v 4.207899 1.983562 3.474449 -v 4.179600 4.271559 3.508932 -v 4.334322 4.205184 3.663655 -v 4.476915 4.097396 3.806248 -v 4.601899 3.952338 3.931232 -v 4.704471 3.775584 4.033803 -v 4.780688 3.573927 4.110021 -v 4.827623 3.355116 4.156956 -v 4.843471 3.127560 4.172803 -v 4.827623 2.900005 4.156956 -v 4.780688 2.681194 4.110021 -v 4.704471 2.479537 4.033803 -v 4.601899 2.302783 3.931232 -v 4.476915 2.157725 3.806248 -v 4.334322 2.049937 3.663655 -v 4.179600 1.983562 3.508932 -v 4.145117 4.271559 3.537232 -v 4.266682 4.205184 3.719166 -v 4.378716 4.097396 3.886838 -v 4.476915 3.952338 4.033803 -v 4.557505 3.775584 4.154415 -v 4.617389 3.573927 4.244037 -v 4.654265 3.355116 4.299226 -v 4.666717 3.127560 4.317862 -v 4.654265 2.900005 4.299226 -v 4.617389 2.681194 4.244037 -v 4.557505 2.479537 4.154415 -v 4.476915 2.302783 4.033803 -v 4.378716 2.157725 3.886838 -v 4.266682 2.049937 3.719166 -v 4.145117 1.983562 3.537232 -v 4.105775 4.271559 3.558260 -v 4.189511 4.205184 3.760415 -v 4.266682 4.097396 3.946722 -v 4.334322 3.952338 4.110021 -v 4.389833 3.775584 4.244037 -v 4.431082 3.573927 4.343620 -v 4.456483 3.355116 4.404943 -v 4.465060 3.127560 4.425649 -v 4.456483 2.900005 4.404943 -v 4.431082 2.681194 4.343620 -v 4.389833 2.479537 4.244037 -v 4.334322 2.302783 4.110021 -v 4.266682 2.157725 3.946722 -v 4.189511 2.049937 3.760415 -v 4.105775 1.983562 3.558260 -v 4.063088 4.271559 3.571209 -v 4.105775 4.205184 3.785815 -v 4.145117 4.097396 3.983598 -v 4.179600 3.952338 4.156956 -v 4.207899 3.775584 4.299226 -v 4.228928 3.573927 4.404943 -v 4.241877 3.355116 4.470043 -v 4.246249 3.127560 4.492024 -v 4.241877 2.900005 4.470043 -v 4.228928 2.681194 4.404943 -v 4.207899 2.479537 4.299226 -v 4.179600 2.302783 4.156956 -v 4.145117 2.157725 3.983598 -v 4.105775 2.049937 3.785815 -v 4.063088 1.983562 3.571209 -v 4.018694 4.271559 3.575582 -v 4.018694 4.205184 3.794392 -v 4.018694 4.097396 3.996049 -v 4.018694 3.952338 4.172803 -v 4.018694 3.775584 4.317861 -v 4.018694 3.573927 4.425649 -v 4.018694 3.355116 4.492024 -v 4.018693 3.127560 4.514437 -v 4.018694 2.900005 4.492024 -v 4.018694 2.681194 4.425649 -v 4.018694 2.479537 4.317861 -v 4.018694 2.302783 4.172803 -v 4.018694 2.157725 3.996049 -v 4.018694 2.049937 3.794392 -v 4.018694 1.983562 3.575582 -v 3.974300 4.271559 3.571209 -v 3.931612 4.205184 3.785815 -v 3.892271 4.097396 3.983598 -v 3.857788 3.952338 4.156955 -v 3.829488 3.775584 4.299226 -v 3.808460 3.573927 4.404943 -v 3.795511 3.355116 4.470043 -v 3.791138 3.127560 4.492024 -v 3.795511 2.900005 4.470043 -v 3.808460 2.681194 4.404943 -v 3.829488 2.479537 4.299226 -v 3.857788 2.302783 4.156955 -v 3.892271 2.157725 3.983598 -v 3.931612 2.049937 3.785815 -v 3.974300 1.983562 3.571209 -v 3.931612 4.271559 3.558260 -v 3.847877 4.205184 3.760415 -v 3.770706 4.097396 3.946721 -v 3.703065 3.952338 4.110021 -v 3.647554 3.775584 4.244037 -v 3.606306 3.573927 4.343620 -v 3.580904 3.355116 4.404943 -v 3.572328 3.127560 4.425649 -v 3.580904 2.900005 4.404943 -v 3.606306 2.681194 4.343620 -v 3.647554 2.479537 4.244037 -v 3.703065 2.302783 4.110021 -v 3.770706 2.157725 3.946721 -v 3.847877 2.049937 3.760415 -v 3.931612 1.983562 3.558260 -v 3.892271 4.271559 3.537232 -v 3.770706 4.205184 3.719166 -v 3.658672 4.097396 3.886837 -v 3.560472 3.952338 4.033803 -v 3.479882 3.775584 4.154415 -v 3.419999 3.573927 4.244037 -v 3.383122 3.355116 4.299226 -v 3.370671 3.127560 4.317861 -v 3.383122 2.900005 4.299226 -v 3.419999 2.681194 4.244037 -v 3.479882 2.479537 4.154415 -v 3.560472 2.302783 4.033803 -v 3.658672 2.157725 3.886837 -v 3.770706 2.049937 3.719166 -v 3.892271 1.983562 3.537232 -v 3.857788 4.271559 3.508932 -v 3.703065 4.205184 3.663655 -v 3.560472 4.097396 3.806247 -v 3.435488 3.952338 3.931232 -v 3.332917 3.775584 4.033803 -v 3.256700 3.573927 4.110021 -v 3.209765 3.355116 4.156955 -v 3.193917 3.127560 4.172802 -v 3.209765 2.900005 4.156955 -v 3.256700 2.681194 4.110021 -v 3.332917 2.479537 4.033803 -v 3.435488 2.302783 3.931232 -v 3.560472 2.157725 3.806247 -v 3.703065 2.049937 3.663655 -v 3.857788 1.983562 3.508932 -v 4.018694 1.961149 3.348026 -v 3.829489 4.271559 3.474449 -v 3.647554 4.205184 3.596014 -v 3.479883 4.097396 3.708048 -v 3.332917 3.952338 3.806248 -v 3.212306 3.775584 3.886837 -v 3.122683 3.573927 3.946722 -v 3.067494 3.355116 3.983598 -v 3.048859 3.127560 3.996048 -v 3.067494 2.900005 3.983598 -v 3.122683 2.681194 3.946722 -v 3.212306 2.479537 3.886837 -v 3.332917 2.302783 3.806248 -v 3.479883 2.157725 3.708048 -v 3.647554 2.049937 3.596014 -v 3.829489 1.983562 3.474449 -v 3.808460 4.271559 3.435108 -v 3.606306 4.205184 3.518843 -v 3.419999 4.097396 3.596014 -v 3.256699 3.952338 3.663655 -v 3.122683 3.775584 3.719166 -v 3.023100 3.573927 3.760415 -v 2.961777 3.355116 3.785815 -v 2.941072 3.127560 3.794392 -v 2.961777 2.900005 3.785815 -v 3.023100 2.681194 3.760415 -v 3.122683 2.479537 3.719166 -v 3.256699 2.302783 3.663655 -v 3.419999 2.157725 3.596014 -v 3.606306 2.049937 3.518843 -v 3.808460 1.983562 3.435108 -v 3.795511 4.271559 3.392420 -v 3.580905 4.205184 3.435108 -v 3.383123 4.097396 3.474449 -v 3.209765 3.952338 3.508932 -v 3.067494 3.775584 3.537231 -v 2.961777 3.573927 3.558260 -v 2.896677 3.355116 3.571209 -v 2.874696 3.127560 3.575581 -v 2.896677 2.900005 3.571209 -v 2.961777 2.681194 3.558260 -v 3.067494 2.479537 3.537231 -v 3.209765 2.302783 3.508932 -v 3.383123 2.157725 3.474449 -v 3.580905 2.049937 3.435108 -v 3.795511 1.983562 3.392420 -v 3.791139 4.271559 3.348026 -v 3.572328 4.205184 3.348026 -v 3.370671 4.097396 3.348026 -v 3.193917 3.952338 3.348026 -v 3.048859 3.775584 3.348026 -v 2.941071 3.573927 3.348026 -v 2.874696 3.355116 3.348026 -v 2.852284 3.127560 3.348026 -v 2.874696 2.900005 3.348026 -v 2.941071 2.681194 3.348026 -v 3.048859 2.479537 3.348026 -v 3.193917 2.302783 3.348026 -v 3.370671 2.157725 3.348026 -v 3.572328 2.049937 3.348026 -v 3.791139 1.983562 3.348026 -v 3.795511 4.271559 3.303632 -v 3.580905 4.205184 3.260945 -v 3.383123 4.097396 3.221603 -v 3.209765 3.952338 3.187120 -v 3.067494 3.775584 3.158821 -v 2.961777 3.573927 3.137793 -v 2.896677 3.355116 3.124843 -v 2.874696 3.127560 3.120471 -v 2.896677 2.900005 3.124843 -v 2.961777 2.681194 3.137793 -v 3.067494 2.479537 3.158821 -v 3.209765 2.302783 3.187120 -v 3.383123 2.157725 3.221603 -v 3.580905 2.049937 3.260945 -v 3.795511 1.983562 3.303632 -v 3.808460 4.271559 3.260945 -v 3.606306 4.205184 3.177209 -v 3.419999 4.097396 3.100039 -v 3.256700 3.952338 3.032398 -v 3.122684 3.775584 2.976886 -v 3.023100 3.573927 2.935638 -v 2.961778 3.355116 2.910237 -v 2.941072 3.127560 2.901660 -v 2.961778 2.900005 2.910237 -v 3.023100 2.681194 2.935638 -v 3.122684 2.479537 2.976886 -v 3.256700 2.302783 3.032398 -v 3.419999 2.157725 3.100039 -v 3.606306 2.049937 3.177209 -v 3.808460 1.983562 3.260945 -v 3.829489 4.271559 3.221603 -v 3.647554 4.205184 3.100039 -v 3.479883 4.097396 2.988004 -v 3.332917 3.952338 2.889805 -v 3.212306 3.775584 2.809215 -v 3.122683 3.573927 2.749331 -v 3.067494 3.355116 2.712455 -v 3.048860 3.127560 2.700003 -v 3.067494 2.900005 2.712455 -v 3.122683 2.681194 2.749331 -v 3.212306 2.479537 2.809215 -v 3.332917 2.302783 2.889805 -v 3.479883 2.157725 2.988004 -v 3.647554 2.049937 3.100039 -v 3.829489 1.983562 3.221603 -v 3.857788 4.271559 3.187120 -v 3.703066 4.205184 3.032398 -v 3.560473 4.097396 2.889805 -v 3.435489 3.952338 2.764821 -v 3.332917 3.775584 2.662250 -v 3.256700 3.573927 2.586032 -v 3.209765 3.355116 2.539097 -v 3.193918 3.127560 2.523250 -v 3.209765 2.900005 2.539097 -v 3.256700 2.681194 2.586032 -v 3.332917 2.479537 2.662250 -v 3.435489 2.302783 2.764821 -v 3.560473 2.157725 2.889805 -v 3.703066 2.049937 3.032398 -v 3.857788 1.983562 3.187120 -v 3.892271 4.271559 3.158821 -v 3.770706 4.205184 2.976887 -v 3.658672 4.097396 2.809215 -v 3.560472 3.952338 2.662249 -v 3.479883 3.775584 2.541638 -v 3.419999 3.573927 2.452016 -v 3.383123 3.355116 2.396827 -v 3.370672 3.127560 2.378192 -v 3.383123 2.900005 2.396827 -v 3.419999 2.681194 2.452016 -v 3.479883 2.479537 2.541638 -v 3.560472 2.302783 2.662249 -v 3.658672 2.157725 2.809215 -v 3.770706 2.049937 2.976887 -v 3.892271 1.983562 3.158821 -v 3.931612 4.271559 3.137793 -v 3.847877 4.205184 2.935638 -v 3.770707 4.097396 2.749331 -v 3.703066 3.952338 2.586032 -v 3.647554 3.775584 2.452016 -v 3.606306 3.573927 2.352433 -v 3.580905 3.355116 2.291110 -v 3.572329 3.127560 2.270404 -v 3.580905 2.900005 2.291110 -v 3.606306 2.681194 2.352433 -v 3.647554 2.479537 2.452016 -v 3.703066 2.302783 2.586032 -v 3.770707 2.157725 2.749331 -v 3.847877 2.049937 2.935638 -v 3.931612 1.983562 3.137793 -v 3.974300 4.271559 3.124843 -v 3.931612 4.205184 2.910237 -v 3.892271 4.097396 2.712455 -v 3.857788 3.952338 2.539097 -v 3.829489 3.775584 2.396827 -v 3.808460 3.573927 2.291110 -v 3.795511 3.355116 2.226010 -v 3.791139 3.127560 2.204029 -v 3.795511 2.900005 2.226010 -v 3.808460 2.681194 2.291110 -v 3.829489 2.479537 2.396827 -v 3.857788 2.302783 2.539097 -v 3.892271 2.157725 2.712455 -v 3.931612 2.049937 2.910237 -v 3.974300 1.983562 3.124843 -v 4.018694 4.271559 3.120471 -v 4.018694 4.205184 2.901660 -v 4.018694 3.952338 2.523249 -v 4.018694 3.573927 2.270404 -v 4.018694 2.681194 2.270404 -v 4.018694 2.302783 2.523249 -v 4.018694 2.157725 2.700004 -v 4.018694 2.049937 2.901660 -v 4.018694 1.983562 3.120471 -vn 0.0624 -0.7715 -0.6332 -vn 0.0865 0.4696 -0.8786 -vn 0.0464 -0.8810 -0.4709 -vn 0.0938 0.2890 -0.9527 -vn 0.0286 -0.9565 -0.2902 -vn 0.0975 0.0975 -0.9904 -vn 0.0097 0.9951 -0.0980 -vn 0.0097 -0.9951 -0.0980 -vn 0.0975 -0.0976 -0.9904 -vn 0.0286 0.9565 -0.2902 -vn 0.0938 -0.2890 -0.9527 -vn 0.0464 0.8810 -0.4709 -vn 0.0865 -0.4696 -0.8786 -vn 0.0624 0.7715 -0.6332 -vn 0.0759 -0.6326 -0.7708 -vn 0.0759 0.6326 -0.7708 -vn 0.2248 -0.6326 -0.7412 -vn 0.2248 0.6326 -0.7412 -vn 0.1847 -0.7715 -0.6088 -vn 0.2563 0.4696 -0.8448 -vn 0.1374 -0.8810 -0.4528 -vn 0.2779 0.2890 -0.9161 -vn 0.0846 -0.9565 -0.2790 -vn 0.2889 0.0976 -0.9524 -vn 0.0286 0.9951 -0.0942 -vn 0.0286 -0.9951 -0.0942 -vn 0.2889 -0.0976 -0.9524 -vn 0.0846 0.9565 -0.2790 -vn 0.2779 -0.2890 -0.9161 -vn 0.1374 0.8810 -0.4528 -vn 0.2563 -0.4696 -0.8448 -vn 0.1847 0.7715 -0.6088 -vn 0.0464 0.9951 -0.0869 -vn 0.0464 -0.9951 -0.0869 -vn 0.4691 -0.0975 -0.8777 -vn 0.1374 0.9565 -0.2571 -vn 0.4513 -0.2890 -0.8443 -vn 0.2231 0.8810 -0.4173 -vn 0.4162 -0.4696 -0.7786 -vn 0.2999 0.7715 -0.5611 -vn 0.3651 -0.6326 -0.6831 -vn 0.3651 0.6326 -0.6831 -vn 0.2999 -0.7715 -0.5611 -vn 0.4162 0.4696 -0.7786 -vn 0.2230 -0.8810 -0.4173 -vn 0.4513 0.2890 -0.8443 -vn 0.1374 -0.9565 -0.2571 -vn 0.4691 0.0975 -0.8777 -vn 0.4913 0.6326 -0.5987 -vn 0.4036 -0.7715 -0.4918 -vn 0.5601 0.4696 -0.6825 -vn 0.3002 -0.8810 -0.3658 -vn 0.6073 0.2890 -0.7400 -vn 0.1850 -0.9565 -0.2254 -vn 0.6314 0.0975 -0.7693 -vn 0.0625 0.9951 -0.0761 -vn 0.0625 -0.9951 -0.0761 -vn 0.6314 -0.0975 -0.7693 -vn 0.1850 0.9565 -0.2254 -vn 0.6073 -0.2890 -0.7400 -vn 0.3002 0.8810 -0.3658 -vn 0.5601 -0.4696 -0.6825 -vn 0.4036 0.7715 -0.4918 -vn 0.4913 -0.6326 -0.5987 -vn 0.7693 -0.0975 -0.6314 -vn 0.2254 0.9565 -0.1850 -vn 0.7400 -0.2890 -0.6073 -vn 0.3658 0.8810 -0.3002 -vn 0.6825 -0.4696 -0.5601 -vn 0.4918 0.7715 -0.4036 -vn 0.5987 -0.6326 -0.4913 -vn 0.5987 0.6326 -0.4913 -vn 0.4918 -0.7715 -0.4036 -vn 0.6825 0.4696 -0.5601 -vn 0.3658 -0.8810 -0.3002 -vn 0.7400 0.2890 -0.6073 -vn 0.2254 -0.9566 -0.1850 -vn 0.7693 0.0975 -0.6314 -vn 0.0761 0.9951 -0.0625 -vn 0.0761 -0.9951 -0.0625 -vn 0.5611 -0.7715 -0.2999 -vn 0.7786 0.4696 -0.4162 -vn 0.4173 -0.8810 -0.2230 -vn 0.8443 0.2890 -0.4513 -vn 0.2571 -0.9565 -0.1374 -vn 0.8777 0.0975 -0.4691 -vn 0.0869 0.9951 -0.0464 -vn 0.0869 -0.9951 -0.0464 -vn 0.8777 -0.0975 -0.4691 -vn 0.2571 0.9565 -0.1374 -vn 0.8443 -0.2890 -0.4513 -vn 0.4173 0.8810 -0.2230 -vn 0.7786 -0.4696 -0.4162 -vn 0.5611 0.7715 -0.2999 -vn 0.6831 -0.6326 -0.3651 -vn 0.6831 0.6326 -0.3651 -vn 0.9161 -0.2890 -0.2779 -vn 0.4528 0.8810 -0.1374 -vn 0.8448 -0.4696 -0.2563 -vn 0.6088 0.7715 -0.1847 -vn 0.7412 -0.6326 -0.2248 -vn 0.7412 0.6326 -0.2248 -vn 0.6088 -0.7715 -0.1847 -vn 0.8448 0.4696 -0.2563 -vn 0.4528 -0.8810 -0.1374 -vn 0.9161 0.2890 -0.2779 -vn 0.2790 -0.9565 -0.0846 -vn 0.9524 0.0975 -0.2889 -vn 0.0942 0.9951 -0.0286 -vn 0.0942 -0.9951 -0.0286 -vn 0.9524 -0.0975 -0.2889 -vn 0.2790 0.9565 -0.0846 -vn 0.4709 -0.8810 -0.0464 -vn 0.9527 0.2890 -0.0938 -vn 0.2902 -0.9565 -0.0286 -vn 0.9904 0.0975 -0.0975 -vn 0.0980 0.9951 -0.0097 -vn 0.0980 -0.9951 -0.0097 -vn 0.9904 -0.0975 -0.0975 -vn 0.2902 0.9565 -0.0286 -vn 0.9527 -0.2890 -0.0938 -vn 0.4709 0.8810 -0.0464 -vn 0.8786 -0.4696 -0.0865 -vn 0.6332 0.7715 -0.0624 -vn 0.7708 -0.6326 -0.0759 -vn 0.7708 0.6326 -0.0759 -vn 0.6332 -0.7715 -0.0624 -vn 0.8786 0.4696 -0.0865 -vn 0.4709 0.8810 0.0464 -vn 0.8786 -0.4696 0.0865 -vn 0.6332 0.7715 0.0624 -vn 0.7708 -0.6326 0.0759 -vn 0.7708 0.6326 0.0759 -vn 0.6332 -0.7715 0.0624 -vn 0.8786 0.4696 0.0865 -vn 0.4709 -0.8810 0.0464 -vn 0.9527 0.2890 0.0938 -vn 0.2902 -0.9565 0.0286 -vn 0.9904 0.0975 0.0976 -vn 0.0980 0.9951 0.0097 -vn 0.0980 -0.9951 0.0097 -vn 0.9904 -0.0975 0.0976 -vn 0.2902 0.9565 0.0286 -vn 0.9527 -0.2890 0.0938 -vn 0.9161 0.2890 0.2779 -vn 0.2790 -0.9565 0.0846 -vn 0.9524 0.0975 0.2889 -vn 0.0942 0.9951 0.0286 -vn 0.0942 -0.9951 0.0286 -vn 0.9524 -0.0975 0.2889 -vn 0.2790 0.9565 0.0846 -vn 0.9161 -0.2890 0.2779 -vn 0.4528 0.8810 0.1374 -vn 0.8448 -0.4696 0.2563 -vn 0.6088 0.7715 0.1847 -vn 0.7412 -0.6326 0.2248 -vn 0.7412 0.6326 0.2248 -vn 0.6088 -0.7715 0.1847 -vn 0.8448 0.4696 0.2563 -vn 0.4528 -0.8810 0.1374 -vn 0.7786 -0.4696 0.4162 -vn 0.5611 0.7715 0.2999 -vn 0.6831 -0.6326 0.3651 -vn 0.6831 0.6326 0.3651 -vn 0.5611 -0.7715 0.2999 -vn 0.7786 0.4696 0.4162 -vn 0.4173 -0.8810 0.2230 -vn 0.8443 0.2890 0.4513 -vn 0.2571 -0.9565 0.1374 -vn 0.8777 0.0975 0.4691 -vn 0.0869 0.9951 0.0464 -vn 0.0869 -0.9951 0.0464 -vn 0.8777 -0.0975 0.4691 -vn 0.2571 0.9565 0.1374 -vn 0.8443 -0.2890 0.4513 -vn 0.4173 0.8810 0.2231 -vn 0.2254 -0.9565 0.1850 -vn 0.7693 0.0975 0.6314 -vn 0.0761 0.9951 0.0625 -vn 0.0761 -0.9951 0.0625 -vn 0.7693 -0.0975 0.6314 -vn 0.2254 0.9565 0.1850 -vn 0.7400 -0.2890 0.6073 -vn 0.3658 0.8810 0.3002 -vn 0.6825 -0.4696 0.5601 -vn 0.4918 0.7715 0.4036 -vn 0.5987 -0.6326 0.4913 -vn 0.5987 0.6326 0.4913 -vn 0.4918 -0.7715 0.4036 -vn 0.6825 0.4696 0.5601 -vn 0.3658 -0.8810 0.3002 -vn 0.7400 0.2890 0.6073 -vn 0.4036 0.7715 0.4918 -vn 0.4913 -0.6326 0.5987 -vn 0.4913 0.6326 0.5987 -vn 0.4036 -0.7715 0.4918 -vn 0.5601 0.4696 0.6825 -vn 0.3002 -0.8810 0.3658 -vn 0.6073 0.2890 0.7400 -vn 0.1850 -0.9565 0.2254 -vn 0.6314 0.0975 0.7693 -vn 0.0625 0.9951 0.0761 -vn 0.0625 -0.9951 0.0761 -vn 0.6314 -0.0975 0.7693 -vn 0.1850 0.9565 0.2254 -vn 0.6073 -0.2890 0.7400 -vn 0.3002 0.8810 0.3658 -vn 0.5601 -0.4696 0.6825 -vn 0.4691 0.0975 0.8777 -vn 0.0464 0.9951 0.0869 -vn 0.0464 -0.9951 0.0869 -vn 0.4691 -0.0975 0.8777 -vn 0.1374 0.9565 0.2571 -vn 0.4513 -0.2890 0.8443 -vn 0.2230 0.8810 0.4173 -vn 0.4162 -0.4696 0.7786 -vn 0.2999 0.7715 0.5611 -vn 0.3651 -0.6326 0.6831 -vn 0.3651 0.6326 0.6831 -vn 0.2999 -0.7715 0.5611 -vn 0.4162 0.4696 0.7786 -vn 0.2230 -0.8810 0.4173 -vn 0.4513 0.2890 0.8443 -vn 0.1374 -0.9565 0.2571 -vn 0.2248 -0.6326 0.7412 -vn 0.2248 0.6326 0.7412 -vn 0.1847 -0.7715 0.6088 -vn 0.2563 0.4696 0.8448 -vn 0.1374 -0.8810 0.4528 -vn 0.2779 0.2890 0.9161 -vn 0.0846 -0.9565 0.2790 -vn 0.2889 0.0975 0.9524 -vn 0.0286 0.9951 0.0942 -vn 0.0286 -0.9951 0.0942 -vn 0.2889 -0.0975 0.9524 -vn 0.0846 0.9565 0.2790 -vn 0.2779 -0.2890 0.9161 -vn 0.1374 0.8810 0.4528 -vn 0.2563 -0.4696 0.8448 -vn 0.1847 0.7715 0.6088 -vn 0.0097 -0.9951 0.0980 -vn 0.0975 -0.0975 0.9904 -vn 0.0286 0.9565 0.2902 -vn 0.0938 -0.2890 0.9527 -vn 0.0464 0.8810 0.4709 -vn 0.0865 -0.4696 0.8786 -vn 0.0624 0.7715 0.6332 -vn 0.0759 -0.6326 0.7708 -vn 0.0759 0.6326 0.7708 -vn 0.0624 -0.7715 0.6332 -vn 0.0865 0.4696 0.8786 -vn 0.0464 -0.8810 0.4709 -vn 0.0938 0.2890 0.9527 -vn 0.0286 -0.9565 0.2902 -vn 0.0975 0.0975 0.9904 -vn 0.0097 0.9951 0.0980 -vn -0.0624 -0.7715 0.6332 -vn -0.0865 0.4696 0.8786 -vn -0.0464 -0.8810 0.4709 -vn -0.0938 0.2890 0.9527 -vn -0.0286 -0.9565 0.2902 -vn -0.0976 0.0975 0.9904 -vn -0.0097 0.9951 0.0980 -vn -0.0097 -0.9951 0.0980 -vn -0.0975 -0.0975 0.9904 -vn -0.0286 0.9565 0.2902 -vn -0.0938 -0.2890 0.9527 -vn -0.0464 0.8810 0.4709 -vn -0.0865 -0.4696 0.8786 -vn -0.0624 0.7715 0.6332 -vn -0.0759 -0.6326 0.7708 -vn -0.0759 0.6326 0.7708 -vn -0.0846 0.9565 0.2790 -vn -0.2779 -0.2890 0.9161 -vn -0.1374 0.8810 0.4528 -vn -0.2563 -0.4696 0.8448 -vn -0.1847 0.7715 0.6088 -vn -0.2248 -0.6326 0.7412 -vn -0.2248 0.6326 0.7412 -vn -0.1847 -0.7715 0.6088 -vn -0.2563 0.4696 0.8448 -vn -0.1374 -0.8810 0.4528 -vn -0.2779 0.2890 0.9161 -vn -0.0846 -0.9565 0.2790 -vn -0.2889 0.0975 0.9524 -vn -0.0286 0.9951 0.0942 -vn -0.0286 -0.9951 0.0942 -vn -0.2889 -0.0975 0.9524 -vn -0.4162 0.4696 0.7786 -vn -0.2230 -0.8810 0.4173 -vn -0.4513 0.2890 0.8443 -vn -0.1374 -0.9565 0.2571 -vn -0.4691 0.0975 0.8777 -vn -0.0464 0.9951 0.0869 -vn -0.0464 -0.9951 0.0869 -vn -0.4691 -0.0975 0.8777 -vn -0.1374 0.9565 0.2571 -vn -0.4513 -0.2890 0.8443 -vn -0.2230 0.8810 0.4173 -vn -0.4162 -0.4696 0.7786 -vn -0.2999 0.7715 0.5611 -vn -0.3651 -0.6326 0.6831 -vn -0.3651 0.6326 0.6831 -vn -0.2999 -0.7715 0.5611 -vn -0.6073 -0.2890 0.7400 -vn -0.3002 0.8810 0.3658 -vn -0.5601 -0.4696 0.6825 -vn -0.4036 0.7715 0.4918 -vn -0.4913 -0.6326 0.5987 -vn -0.4913 0.6326 0.5987 -vn -0.4036 -0.7715 0.4918 -vn -0.5601 0.4696 0.6825 -vn -0.3002 -0.8810 0.3658 -vn -0.6073 0.2890 0.7400 -vn -0.1850 -0.9565 0.2254 -vn -0.6314 0.0975 0.7693 -vn -0.0625 0.9951 0.0761 -vn -0.0625 -0.9951 0.0761 -vn -0.6314 -0.0975 0.7693 -vn -0.1850 0.9565 0.2254 -vn -0.3658 -0.8810 0.3002 -vn -0.7400 0.2890 0.6073 -vn -0.2254 -0.9566 0.1850 -vn -0.7693 0.0975 0.6314 -vn -0.0761 0.9951 0.0625 -vn -0.0761 -0.9951 0.0625 -vn -0.7693 -0.0975 0.6314 -vn -0.2254 0.9565 0.1850 -vn -0.7400 -0.2890 0.6073 -vn -0.3658 0.8810 0.3002 -vn -0.6825 -0.4696 0.5601 -vn -0.4918 0.7715 0.4036 -vn -0.5987 -0.6326 0.4913 -vn -0.5987 0.6326 0.4913 -vn -0.4918 -0.7715 0.4036 -vn -0.6825 0.4696 0.5601 -vn -0.4173 0.8810 0.2230 -vn -0.7786 -0.4696 0.4162 -vn -0.5611 0.7715 0.2999 -vn -0.6831 -0.6326 0.3651 -vn -0.6831 0.6326 0.3651 -vn -0.5611 -0.7715 0.2999 -vn -0.7786 0.4696 0.4162 -vn -0.4173 -0.8810 0.2231 -vn -0.8443 0.2890 0.4513 -vn -0.2571 -0.9565 0.1374 -vn -0.8777 0.0975 0.4691 -vn -0.0869 0.9951 0.0464 -vn -0.0869 -0.9951 0.0464 -vn -0.8777 -0.0975 0.4691 -vn -0.2571 0.9565 0.1374 -vn -0.8443 -0.2890 0.4513 -vn -0.9161 0.2890 0.2779 -vn -0.2790 -0.9565 0.0846 -vn -0.9524 0.0975 0.2889 -vn -0.0942 0.9951 0.0286 -vn -0.0942 -0.9951 0.0286 -vn -0.9524 -0.0975 0.2889 -vn -0.2790 0.9565 0.0846 -vn -0.9161 -0.2890 0.2779 -vn -0.4528 0.8810 0.1374 -vn -0.8448 -0.4696 0.2563 -vn -0.6088 0.7715 0.1847 -vn -0.7412 -0.6326 0.2248 -vn -0.7412 0.6326 0.2248 -vn -0.6088 -0.7715 0.1847 -vn -0.8448 0.4696 0.2563 -vn -0.4528 -0.8810 0.1374 -vn -0.8786 -0.4696 0.0865 -vn -0.6332 0.7715 0.0624 -vn -0.7708 -0.6326 0.0759 -vn -0.7708 0.6326 0.0759 -vn -0.6332 -0.7715 0.0624 -vn -0.8786 0.4696 0.0865 -vn -0.4709 -0.8810 0.0464 -vn -0.9527 0.2890 0.0938 -vn -0.2902 -0.9565 0.0286 -vn -0.9904 0.0975 0.0975 -vn -0.0980 0.9951 0.0097 -vn -0.0980 -0.9951 0.0097 -vn -0.9904 -0.0975 0.0976 -vn -0.2902 0.9565 0.0286 -vn -0.9527 -0.2890 0.0938 -vn -0.4709 0.8810 0.0464 -vn -0.2902 -0.9565 -0.0286 -vn -0.9904 0.0975 -0.0975 -vn -0.0980 0.9951 -0.0097 -vn -0.0980 -0.9951 -0.0097 -vn -0.9904 -0.0975 -0.0976 -vn -0.2902 0.9565 -0.0286 -vn -0.9527 -0.2890 -0.0938 -vn -0.4709 0.8810 -0.0464 -vn -0.8786 -0.4696 -0.0865 -vn -0.6332 0.7715 -0.0624 -vn -0.7708 -0.6326 -0.0759 -vn -0.7708 0.6326 -0.0759 -vn -0.6332 -0.7715 -0.0624 -vn -0.8786 0.4696 -0.0865 -vn -0.4709 -0.8810 -0.0464 -vn -0.9527 0.2890 -0.0938 -vn -0.7412 -0.6326 -0.2248 -vn -0.7412 0.6326 -0.2248 -vn -0.6088 -0.7715 -0.1847 -vn -0.8448 0.4696 -0.2563 -vn -0.4528 -0.8810 -0.1374 -vn -0.9161 0.2890 -0.2779 -vn -0.2790 -0.9565 -0.0846 -vn -0.9524 0.0975 -0.2889 -vn -0.0942 0.9951 -0.0286 -vn -0.0942 -0.9951 -0.0286 -vn -0.9524 -0.0975 -0.2889 -vn -0.2790 0.9565 -0.0846 -vn -0.9161 -0.2890 -0.2779 -vn -0.4528 0.8810 -0.1374 -vn -0.8448 -0.4696 -0.2563 -vn -0.6088 0.7715 -0.1847 -vn -0.0869 0.9951 -0.0464 -vn -0.0869 -0.9951 -0.0464 -vn -0.8777 -0.0975 -0.4691 -vn -0.2571 0.9565 -0.1374 -vn -0.8443 -0.2890 -0.4513 -vn -0.4173 0.8810 -0.2231 -vn -0.7786 -0.4696 -0.4162 -vn -0.5611 0.7715 -0.2999 -vn -0.6831 -0.6326 -0.3651 -vn -0.6831 0.6326 -0.3651 -vn -0.5611 -0.7715 -0.2999 -vn -0.7786 0.4696 -0.4162 -vn -0.4173 -0.8810 -0.2231 -vn -0.8443 0.2890 -0.4513 -vn -0.2571 -0.9565 -0.1374 -vn -0.8777 0.0975 -0.4691 -vn -0.5987 0.6326 -0.4913 -vn -0.4918 -0.7715 -0.4036 -vn -0.6825 0.4696 -0.5601 -vn -0.3658 -0.8810 -0.3002 -vn -0.7400 0.2890 -0.6073 -vn -0.2254 -0.9565 -0.1850 -vn -0.7693 0.0975 -0.6314 -vn -0.0761 0.9951 -0.0625 -vn -0.0761 -0.9951 -0.0625 -vn -0.7693 -0.0975 -0.6314 -vn -0.2254 0.9565 -0.1850 -vn -0.7400 -0.2890 -0.6073 -vn -0.3658 0.8810 -0.3002 -vn -0.6825 -0.4696 -0.5601 -vn -0.4918 0.7715 -0.4036 -vn -0.5987 -0.6326 -0.4913 -vn -0.6314 -0.0975 -0.7693 -vn -0.1850 0.9565 -0.2254 -vn -0.6073 -0.2890 -0.7400 -vn -0.3002 0.8810 -0.3658 -vn -0.5601 -0.4696 -0.6825 -vn -0.4036 0.7715 -0.4918 -vn -0.4913 -0.6326 -0.5987 -vn -0.4913 0.6326 -0.5987 -vn -0.4036 -0.7715 -0.4918 -vn -0.5601 0.4696 -0.6825 -vn -0.3002 -0.8810 -0.3658 -vn -0.6073 0.2890 -0.7400 -vn -0.1850 -0.9565 -0.2254 -vn -0.6314 0.0975 -0.7693 -vn -0.0625 0.9951 -0.0761 -vn -0.0625 -0.9951 -0.0761 -vn -0.2999 -0.7715 -0.5611 -vn -0.4162 0.4696 -0.7786 -vn -0.2230 -0.8810 -0.4173 -vn -0.4513 0.2890 -0.8443 -vn -0.1374 -0.9565 -0.2571 -vn -0.4691 0.0975 -0.8777 -vn -0.0464 0.9951 -0.0869 -vn -0.0464 -0.9951 -0.0869 -vn -0.4691 -0.0975 -0.8777 -vn -0.1374 0.9565 -0.2571 -vn -0.4513 -0.2890 -0.8443 -vn -0.2230 0.8810 -0.4173 -vn -0.4162 -0.4696 -0.7786 -vn -0.2999 0.7715 -0.5611 -vn -0.3651 -0.6326 -0.6831 -vn -0.3651 0.6326 -0.6831 -vn -0.0846 0.9565 -0.2790 -vn -0.2779 -0.2890 -0.9161 -vn -0.1374 0.8810 -0.4528 -vn -0.2563 -0.4696 -0.8448 -vn -0.1847 0.7715 -0.6088 -vn -0.2248 -0.6326 -0.7412 -vn -0.2248 0.6326 -0.7412 -vn -0.1847 -0.7715 -0.6088 -vn -0.2563 0.4696 -0.8448 -vn -0.1374 -0.8810 -0.4528 -vn -0.2779 0.2890 -0.9161 -vn -0.0846 -0.9565 -0.2790 -vn -0.2889 0.0975 -0.9524 -vn -0.0286 0.9951 -0.0942 -vn -0.0286 -0.9951 -0.0942 -vn -0.2889 -0.0975 -0.9524 -vn -0.0865 0.4696 -0.8786 -vn -0.0464 -0.8810 -0.4709 -vn -0.0938 0.2890 -0.9527 -vn -0.0286 -0.9565 -0.2902 -vn -0.0976 0.0975 -0.9904 -vn -0.0097 0.9951 -0.0980 -vn -0.0097 -0.9951 -0.0980 -vn -0.0976 -0.0975 -0.9904 -vn -0.0286 0.9565 -0.2902 -vn -0.0938 -0.2890 -0.9527 -vn -0.0464 0.8810 -0.4709 -vn -0.0865 -0.4696 -0.8786 -vn -0.0624 0.7715 -0.6332 -vn -0.0759 -0.6326 -0.7708 -vn -0.0759 0.6326 -0.7708 -vn -0.0624 -0.7715 -0.6332 -vn 0.0975 0.0976 -0.9904 -vn 0.0975 -0.0975 -0.9904 -vn 0.2230 0.8810 -0.4173 -vn 0.2231 -0.8810 -0.4173 -vn 0.2254 -0.9565 -0.1850 -vn 0.4173 -0.8810 0.2231 -vn 0.2571 0.9566 0.1374 -vn 0.4173 0.8810 0.2230 -vn 0.2231 -0.8810 0.4173 -vn -0.0975 0.0975 0.9904 -vn -0.0976 -0.0975 0.9904 -vn -0.2231 -0.8810 0.4173 -vn -0.2231 0.8810 0.4173 -vn -0.2254 -0.9565 0.1850 -vn -0.4173 -0.8810 0.2230 -vn -0.9904 0.0975 0.0976 -vn -0.9904 -0.0975 0.0975 -vn -0.9904 0.0975 -0.0976 -vn -0.9904 -0.0975 -0.0975 -vt 0.750000 0.812500 -vt 0.750000 0.687500 -vt 0.750000 0.562500 -vt 0.750000 0.500000 -vt 0.750000 0.437500 -vt 0.750000 0.312500 -vt 0.718750 0.937500 -vt 0.718750 0.875000 -vt 0.718750 0.812500 -vt 0.718750 0.750000 -vt 0.718750 0.687500 -vt 0.718750 0.625000 -vt 0.718750 0.562500 -vt 0.718750 0.500000 -vt 0.718750 0.437500 -vt 0.718750 0.375000 -vt 0.718750 0.312500 -vt 0.718750 0.250000 -vt 0.718750 0.187500 -vt 0.718750 0.125000 -vt 0.718750 0.062500 -vt 0.687500 0.937500 -vt 0.687500 0.875000 -vt 0.687500 0.812500 -vt 0.687500 0.750000 -vt 0.687500 0.687500 -vt 0.687500 0.625000 -vt 0.687500 0.562500 -vt 0.687500 0.500000 -vt 0.687500 0.437500 -vt 0.687500 0.375000 -vt 0.687500 0.312500 -vt 0.687500 0.250000 -vt 0.687500 0.187500 -vt 0.687500 0.125000 -vt 0.687500 0.062500 -vt 0.656250 0.937500 -vt 0.656250 0.875000 -vt 0.656250 0.812500 -vt 0.656250 0.750000 -vt 0.656250 0.687500 -vt 0.656250 0.625000 -vt 0.656250 0.562500 -vt 0.656250 0.500000 -vt 0.656250 0.437500 -vt 0.656250 0.375000 -vt 0.656250 0.312500 -vt 0.656250 0.250000 -vt 0.656250 0.187500 -vt 0.656250 0.125000 -vt 0.656250 0.062500 -vt 0.625000 0.937500 -vt 0.625000 0.875000 -vt 0.625000 0.812500 -vt 0.625000 0.750000 -vt 0.625000 0.687500 -vt 0.625000 0.625000 -vt 0.625000 0.562500 -vt 0.625000 0.500000 -vt 0.625000 0.437500 -vt 0.625000 0.375000 -vt 0.625000 0.312500 -vt 0.625000 0.250000 -vt 0.625000 0.187500 -vt 0.625000 0.125000 -vt 0.625000 0.062500 -vt 0.593750 0.937500 -vt 0.593750 0.875000 -vt 0.593750 0.812500 -vt 0.593750 0.750000 -vt 0.593750 0.687500 -vt 0.593750 0.625000 -vt 0.593750 0.562500 -vt 0.593750 0.500000 -vt 0.593750 0.437500 -vt 0.593750 0.375000 -vt 0.593750 0.312500 -vt 0.593750 0.250000 -vt 0.593750 0.187500 -vt 0.593750 0.125000 -vt 0.593750 0.062500 -vt 0.734375 1.000000 -vt 0.703125 1.000000 -vt 0.671875 1.000000 -vt 0.640625 1.000000 -vt 0.609375 1.000000 -vt 0.578125 1.000000 -vt 0.546875 1.000000 -vt 0.515625 1.000000 -vt 0.484375 1.000000 -vt 0.453125 1.000000 -vt 0.421875 1.000000 -vt 0.390625 1.000000 -vt 0.359375 1.000000 -vt 0.328125 1.000000 -vt 0.296875 1.000000 -vt 0.265625 1.000000 -vt 0.234375 1.000000 -vt 0.203125 1.000000 -vt 0.171875 1.000000 -vt 0.140625 1.000000 -vt 0.109375 1.000000 -vt 0.078125 1.000000 -vt 0.046875 1.000000 -vt 0.015625 1.000000 -vt 0.984375 1.000000 -vt 0.953125 1.000000 -vt 0.921875 1.000000 -vt 0.890625 1.000000 -vt 0.859375 1.000000 -vt 0.828125 1.000000 -vt 0.796875 1.000000 -vt 0.765625 1.000000 -vt 0.562500 0.937500 -vt 0.562500 0.875000 -vt 0.562500 0.812500 -vt 0.562500 0.750000 -vt 0.562500 0.687500 -vt 0.562500 0.625000 -vt 0.562500 0.562500 -vt 0.562500 0.500000 -vt 0.562500 0.437500 -vt 0.562500 0.375000 -vt 0.562500 0.312500 -vt 0.562500 0.250000 -vt 0.562500 0.187500 -vt 0.562500 0.125000 -vt 0.562500 0.062500 -vt 0.531250 0.937500 -vt 0.531250 0.875000 -vt 0.531250 0.812500 -vt 0.531250 0.750000 -vt 0.531250 0.687500 -vt 0.531250 0.625000 -vt 0.531250 0.562500 -vt 0.531250 0.500000 -vt 0.531250 0.437500 -vt 0.531250 0.375000 -vt 0.531250 0.312500 -vt 0.531250 0.250000 -vt 0.531250 0.187500 -vt 0.531250 0.125000 -vt 0.531250 0.062500 -vt 0.500000 0.937500 -vt 0.500000 0.875000 -vt 0.500000 0.812500 -vt 0.500000 0.750000 -vt 0.500000 0.687500 -vt 0.500000 0.625000 -vt 0.500000 0.562500 -vt 0.500000 0.500000 -vt 0.500000 0.437500 -vt 0.500000 0.375000 -vt 0.500000 0.312500 -vt 0.500000 0.250000 -vt 0.500000 0.187500 -vt 0.500000 0.125000 -vt 0.500000 0.062500 -vt 0.468750 0.937500 -vt 0.468750 0.875000 -vt 0.468750 0.812500 -vt 0.468750 0.750000 -vt 0.468750 0.687500 -vt 0.468750 0.625000 -vt 0.468750 0.562500 -vt 0.468750 0.500000 -vt 0.468750 0.437500 -vt 0.468750 0.375000 -vt 0.468750 0.312500 -vt 0.468750 0.250000 -vt 0.468750 0.187500 -vt 0.468750 0.125000 -vt 0.468750 0.062500 -vt 0.437500 0.937500 -vt 0.437500 0.875000 -vt 0.437500 0.812500 -vt 0.437500 0.750000 -vt 0.437500 0.687500 -vt 0.437500 0.625000 -vt 0.437500 0.562500 -vt 0.437500 0.500000 -vt 0.437500 0.437500 -vt 0.437500 0.375000 -vt 0.437500 0.312500 -vt 0.437500 0.250000 -vt 0.437500 0.187500 -vt 0.437500 0.125000 -vt 0.437500 0.062500 -vt 0.406250 0.937500 -vt 0.406250 0.875000 -vt 0.406250 0.812500 -vt 0.406250 0.750000 -vt 0.406250 0.687500 -vt 0.406250 0.625000 -vt 0.406250 0.562500 -vt 0.406250 0.500000 -vt 0.406250 0.437500 -vt 0.406250 0.375000 -vt 0.406250 0.312500 -vt 0.406250 0.250000 -vt 0.406250 0.187500 -vt 0.406250 0.125000 -vt 0.406250 0.062500 -vt 0.375000 0.937500 -vt 0.375000 0.875000 -vt 0.375000 0.812500 -vt 0.375000 0.750000 -vt 0.375000 0.687500 -vt 0.375000 0.625000 -vt 0.375000 0.562500 -vt 0.375000 0.500000 -vt 0.375000 0.437500 -vt 0.375000 0.375000 -vt 0.375000 0.312500 -vt 0.375000 0.250000 -vt 0.375000 0.187500 -vt 0.375000 0.125000 -vt 0.375000 0.062500 -vt 0.343750 0.937500 -vt 0.343750 0.875000 -vt 0.343750 0.812500 -vt 0.343750 0.750000 -vt 0.343750 0.687500 -vt 0.343750 0.625000 -vt 0.343750 0.562500 -vt 0.343750 0.500000 -vt 0.343750 0.437500 -vt 0.343750 0.375000 -vt 0.343750 0.312500 -vt 0.343750 0.250000 -vt 0.343750 0.187500 -vt 0.343750 0.125000 -vt 0.343750 0.062500 -vt 0.312500 0.937500 -vt 0.312500 0.875000 -vt 0.312500 0.812500 -vt 0.312500 0.750000 -vt 0.312500 0.687500 -vt 0.312500 0.625000 -vt 0.312500 0.562500 -vt 0.312500 0.500000 -vt 0.312500 0.437500 -vt 0.312500 0.375000 -vt 0.312500 0.312500 -vt 0.312500 0.250000 -vt 0.312500 0.187500 -vt 0.312500 0.125000 -vt 0.312500 0.062500 -vt 0.281250 0.937500 -vt 0.281250 0.875000 -vt 0.281250 0.812500 -vt 0.281250 0.750000 -vt 0.281250 0.687500 -vt 0.281250 0.625000 -vt 0.281250 0.562500 -vt 0.281250 0.500000 -vt 0.281250 0.437500 -vt 0.281250 0.375000 -vt 0.281250 0.312500 -vt 0.281250 0.250000 -vt 0.281250 0.187500 -vt 0.281250 0.125000 -vt 0.281250 0.062500 -vt 0.250000 0.937500 -vt 0.250000 0.875000 -vt 0.250000 0.812500 -vt 0.250000 0.750000 -vt 0.250000 0.687500 -vt 0.250000 0.625000 -vt 0.250000 0.562500 -vt 0.250000 0.500000 -vt 0.250000 0.437500 -vt 0.250000 0.375000 -vt 0.250000 0.312500 -vt 0.250000 0.250000 -vt 0.250000 0.187500 -vt 0.250000 0.125000 -vt 0.250000 0.062500 -vt 0.218750 0.937500 -vt 0.218750 0.875000 -vt 0.218750 0.812500 -vt 0.218750 0.750000 -vt 0.218750 0.687500 -vt 0.218750 0.625000 -vt 0.218750 0.562500 -vt 0.218750 0.500000 -vt 0.218750 0.437500 -vt 0.218750 0.375000 -vt 0.218750 0.312500 -vt 0.218750 0.250000 -vt 0.218750 0.187500 -vt 0.218750 0.125000 -vt 0.218750 0.062500 -vt 0.187500 0.937500 -vt 0.187500 0.875000 -vt 0.187500 0.812500 -vt 0.187500 0.750000 -vt 0.187500 0.687500 -vt 0.187500 0.625000 -vt 0.187500 0.562500 -vt 0.187500 0.500000 -vt 0.187500 0.437500 -vt 0.187500 0.375000 -vt 0.187500 0.312500 -vt 0.187500 0.250000 -vt 0.187500 0.187500 -vt 0.187500 0.125000 -vt 0.187500 0.062500 -vt 0.156250 0.937500 -vt 0.156250 0.875000 -vt 0.156250 0.812500 -vt 0.156250 0.750000 -vt 0.156250 0.687500 -vt 0.156250 0.625000 -vt 0.156250 0.562500 -vt 0.156250 0.500000 -vt 0.156250 0.437500 -vt 0.156250 0.375000 -vt 0.156250 0.312500 -vt 0.156250 0.250000 -vt 0.156250 0.187500 -vt 0.156250 0.125000 -vt 0.156250 0.062500 -vt 0.125000 0.937500 -vt 0.125000 0.875000 -vt 0.125000 0.812500 -vt 0.125000 0.750000 -vt 0.125000 0.687500 -vt 0.125000 0.625000 -vt 0.125000 0.562500 -vt 0.125000 0.500000 -vt 0.125000 0.437500 -vt 0.125000 0.375000 -vt 0.125000 0.312500 -vt 0.125000 0.250000 -vt 0.125000 0.187500 -vt 0.125000 0.125000 -vt 0.125000 0.062500 -vt 0.734375 0.000000 -vt 0.703125 0.000000 -vt 0.671875 0.000000 -vt 0.640625 0.000000 -vt 0.609375 0.000000 -vt 0.578125 0.000000 -vt 0.546875 0.000000 -vt 0.515625 0.000000 -vt 0.484375 0.000000 -vt 0.453125 0.000000 -vt 0.421875 0.000000 -vt 0.390625 0.000000 -vt 0.359375 0.000000 -vt 0.328125 0.000000 -vt 0.296875 0.000000 -vt 0.265625 0.000000 -vt 0.234375 0.000000 -vt 0.203125 0.000000 -vt 0.171875 0.000000 -vt 0.140625 0.000000 -vt 0.109375 0.000000 -vt 0.078125 0.000000 -vt 0.046875 0.000000 -vt 0.015625 0.000000 -vt 0.984375 0.000000 -vt 0.953125 0.000000 -vt 0.921875 0.000000 -vt 0.890625 0.000000 -vt 0.859375 0.000000 -vt 0.828125 0.000000 -vt 0.796875 0.000000 -vt 0.765625 0.000000 -vt 0.093750 0.937500 -vt 0.093750 0.875000 -vt 0.093750 0.812500 -vt 0.093750 0.750000 -vt 0.093750 0.687500 -vt 0.093750 0.625000 -vt 0.093750 0.562500 -vt 0.093750 0.500000 -vt 0.093750 0.437500 -vt 0.093750 0.375000 -vt 0.093750 0.312500 -vt 0.093750 0.250000 -vt 0.093750 0.187500 -vt 0.093750 0.125000 -vt 0.093750 0.062500 -vt 0.062500 0.937500 -vt 0.062500 0.875000 -vt 0.062500 0.812500 -vt 0.062500 0.750000 -vt 0.062500 0.687500 -vt 0.062500 0.625000 -vt 0.062500 0.562500 -vt 0.062500 0.500000 -vt 0.062500 0.437500 -vt 0.062500 0.375000 -vt 0.062500 0.312500 -vt 0.062500 0.250000 -vt 0.062500 0.187500 -vt 0.062500 0.125000 -vt 0.062500 0.062500 -vt 0.031250 0.937500 -vt 0.031250 0.875000 -vt 0.031250 0.812500 -vt 0.031250 0.750000 -vt 0.031250 0.687500 -vt 0.031250 0.625000 -vt 0.031250 0.562500 -vt 0.031250 0.500000 -vt 0.031250 0.437500 -vt 0.031250 0.375000 -vt 0.031250 0.312500 -vt 0.031250 0.250000 -vt 0.031250 0.187500 -vt 0.031250 0.125000 -vt 0.031250 0.062500 -vt 0.000000 0.937500 -vt 1.000000 0.937500 -vt 0.000000 0.875000 -vt 1.000000 0.875000 -vt 0.000000 0.812500 -vt 1.000000 0.812500 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 0.000000 0.687500 -vt 1.000000 0.687500 -vt 0.000000 0.625000 -vt 1.000000 0.625000 -vt 0.000000 0.562500 -vt 1.000000 0.562500 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.437500 -vt 1.000000 0.437500 -vt 0.000000 0.375000 -vt 1.000000 0.375000 -vt 0.000000 0.312500 -vt 1.000000 0.312500 -vt 0.000000 0.250000 -vt 1.000000 0.250000 -vt 0.000000 0.187500 -vt 1.000000 0.187500 -vt 0.000000 0.125000 -vt 1.000000 0.125000 -vt 1.000000 0.062500 -vt 0.000000 0.062500 -vt 0.968750 0.937500 -vt 0.968750 0.875000 -vt 0.968750 0.812500 -vt 0.968750 0.750000 -vt 0.968750 0.687500 -vt 0.968750 0.625000 -vt 0.968750 0.562500 -vt 0.968750 0.500000 -vt 0.968750 0.437500 -vt 0.968750 0.375000 -vt 0.968750 0.312500 -vt 0.968750 0.250000 -vt 0.968750 0.187500 -vt 0.968750 0.125000 -vt 0.968750 0.062500 -vt 0.937500 0.937500 -vt 0.937500 0.875000 -vt 0.937500 0.812500 -vt 0.937500 0.750000 -vt 0.937500 0.687500 -vt 0.937500 0.625000 -vt 0.937500 0.562500 -vt 0.937500 0.500000 -vt 0.937500 0.437500 -vt 0.937500 0.375000 -vt 0.937500 0.312500 -vt 0.937500 0.250000 -vt 0.937500 0.187500 -vt 0.937500 0.125000 -vt 0.937500 0.062500 -vt 0.906250 0.937500 -vt 0.906250 0.875000 -vt 0.906250 0.812500 -vt 0.906250 0.750000 -vt 0.906250 0.687500 -vt 0.906250 0.625000 -vt 0.906250 0.562500 -vt 0.906250 0.500000 -vt 0.906250 0.437500 -vt 0.906250 0.375000 -vt 0.906250 0.312500 -vt 0.906250 0.250000 -vt 0.906250 0.187500 -vt 0.906250 0.125000 -vt 0.906250 0.062500 -vt 0.875000 0.937500 -vt 0.875000 0.875000 -vt 0.875000 0.812500 -vt 0.875000 0.750000 -vt 0.875000 0.687500 -vt 0.875000 0.625000 -vt 0.875000 0.562500 -vt 0.875000 0.500000 -vt 0.875000 0.437500 -vt 0.875000 0.375000 -vt 0.875000 0.312500 -vt 0.875000 0.250000 -vt 0.875000 0.187500 -vt 0.875000 0.125000 -vt 0.875000 0.062500 -vt 0.843750 0.937500 -vt 0.843750 0.875000 -vt 0.843750 0.812500 -vt 0.843750 0.750000 -vt 0.843750 0.687500 -vt 0.843750 0.625000 -vt 0.843750 0.562500 -vt 0.843750 0.500000 -vt 0.843750 0.437500 -vt 0.843750 0.375000 -vt 0.843750 0.312500 -vt 0.843750 0.250000 -vt 0.843750 0.187500 -vt 0.843750 0.125000 -vt 0.843750 0.062500 -vt 0.812500 0.937500 -vt 0.812500 0.875000 -vt 0.812500 0.812500 -vt 0.812500 0.750000 -vt 0.812500 0.687500 -vt 0.812500 0.625000 -vt 0.812500 0.562500 -vt 0.812500 0.500000 -vt 0.812500 0.437500 -vt 0.812500 0.375000 -vt 0.812500 0.312500 -vt 0.812500 0.250000 -vt 0.812500 0.187500 -vt 0.812500 0.125000 -vt 0.812500 0.062500 -vt 0.781250 0.937500 -vt 0.781250 0.875000 -vt 0.781250 0.812500 -vt 0.781250 0.750000 -vt 0.781250 0.687500 -vt 0.781250 0.625000 -vt 0.781250 0.562500 -vt 0.781250 0.500000 -vt 0.781250 0.437500 -vt 0.781250 0.375000 -vt 0.781250 0.312500 -vt 0.781250 0.250000 -vt 0.781250 0.187500 -vt 0.781250 0.125000 -vt 0.781250 0.062500 -vt 0.750000 0.937500 -vt 0.750000 0.875000 -vt 0.750000 0.750000 -vt 0.750000 0.625000 -vt 0.750000 0.375000 -vt 0.750000 0.250000 -vt 0.750000 0.187500 -vt 0.750000 0.125000 -vt 0.750000 0.062500 -f 479/556/1 19/19/1 480/557/1 -f 477/554/2 11/11/2 12/12/2 -f 480/557/3 20/20/3 481/558/3 -f 3/3/4 12/12/4 13/13/4 -f 481/558/5 21/21/5 482/559/5 -f 3/3/6 14/14/6 4/4/6 -f 474/551/7 82/82/7 7/7/7 -f 308/339/8 482/559/8 21/21/8 -f 4/4/9 15/15/9 5/5/9 -f 475/552/10 7/7/10 8/8/10 -f 5/5/11 16/16/11 478/555/11 -f 1/1/12 8/8/12 9/9/12 -f 478/555/13 17/17/13 6/6/13 -f 476/553/14 9/9/14 10/10/14 -f 6/6/15 18/18/15 479/556/15 -f 2/2/16 10/10/16 11/11/16 -f 17/17/17 33/33/17 18/18/17 -f 10/10/18 26/26/18 11/11/18 -f 19/19/19 33/33/19 34/34/19 -f 11/11/20 27/27/20 12/12/20 -f 20/20/21 34/34/21 35/35/21 -f 13/13/22 27/27/22 28/28/22 -f 20/20/23 36/36/23 21/21/23 -f 13/13/24 29/29/24 14/14/24 -f 7/7/25 82/83/25 22/22/25 -f 308/340/26 21/21/26 36/36/26 -f 14/14/27 30/30/27 15/15/27 -f 7/7/28 23/23/28 8/8/28 -f 15/15/29 31/31/29 16/16/29 -f 8/8/30 24/24/30 9/9/30 -f 16/16/31 32/32/31 17/17/31 -f 9/9/32 25/25/32 10/10/32 -f 22/22/33 82/84/33 37/37/33 -f 308/341/34 36/36/34 51/51/34 -f 30/30/35 44/44/35 45/45/35 -f 22/22/36 38/38/36 23/23/36 -f 30/30/37 46/46/37 31/31/37 -f 23/23/38 39/39/38 24/24/38 -f 32/32/39 46/46/39 47/47/39 -f 24/24/40 40/40/40 25/25/40 -f 33/33/41 47/47/41 48/48/41 -f 25/25/42 41/41/42 26/26/42 -f 34/34/43 48/48/43 49/49/43 -f 26/26/44 42/42/44 27/27/44 -f 34/34/45 50/50/45 35/35/45 -f 27/27/46 43/43/46 28/28/46 -f 35/35/47 51/51/47 36/36/47 -f 28/28/48 44/44/48 29/29/48 -f 40/40/49 56/56/49 41/41/49 -f 48/48/50 64/64/50 49/49/50 -f 41/41/51 57/57/51 42/42/51 -f 49/49/52 65/65/52 50/50/52 -f 43/43/53 57/57/53 58/58/53 -f 50/50/54 66/66/54 51/51/54 -f 44/44/55 58/58/55 59/59/55 -f 37/37/56 82/85/56 52/52/56 -f 308/342/57 51/51/57 66/66/57 -f 44/44/58 60/60/58 45/45/58 -f 37/37/59 53/53/59 38/38/59 -f 45/45/60 61/61/60 46/46/60 -f 38/38/61 54/54/61 39/39/61 -f 47/47/62 61/61/62 62/62/62 -f 39/39/63 55/55/63 40/40/63 -f 47/47/64 63/63/64 48/48/64 -f 59/59/65 75/75/65 60/60/65 -f 52/52/66 68/68/66 53/53/66 -f 60/60/67 76/76/67 61/61/67 -f 53/53/68 69/69/68 54/54/68 -f 62/62/69 76/76/69 77/77/69 -f 54/54/70 70/70/70 55/55/70 -f 62/62/71 78/78/71 63/63/71 -f 56/56/72 70/70/72 71/71/72 -f 63/63/73 79/79/73 64/64/73 -f 56/56/74 72/72/74 57/57/74 -f 65/65/75 79/79/75 80/80/75 -f 58/58/76 72/72/76 73/73/76 -f 65/65/77 81/81/77 66/66/77 -f 59/59/78 73/73/78 74/74/78 -f 52/52/79 82/86/79 67/67/79 -f 308/343/80 66/66/80 81/81/80 -f 78/78/81 95/126/81 79/79/81 -f 71/71/82 88/119/82 72/72/82 -f 79/79/83 96/127/83 80/80/83 -f 73/73/84 88/119/84 89/120/84 -f 81/81/85 96/127/85 97/128/85 -f 74/74/86 89/120/86 90/121/86 -f 67/67/87 82/87/87 83/114/87 -f 308/344/88 81/81/88 97/128/88 -f 74/74/89 91/122/89 75/75/89 -f 67/67/90 84/115/90 68/68/90 -f 75/75/91 92/123/91 76/76/91 -f 68/68/92 85/116/92 69/69/92 -f 77/77/93 92/123/93 93/124/93 -f 69/69/94 86/117/94 70/70/94 -f 77/77/95 94/125/95 78/78/95 -f 71/71/96 86/117/96 87/118/96 -f 91/122/97 107/138/97 92/123/97 -f 84/115/98 100/131/98 85/116/98 -f 93/124/99 107/138/99 108/139/99 -f 85/116/100 101/132/100 86/117/100 -f 93/124/101 109/140/101 94/125/101 -f 87/118/102 101/132/102 102/133/102 -f 95/126/103 109/140/103 110/141/103 -f 87/118/104 103/134/104 88/119/104 -f 96/127/105 110/141/105 111/142/105 -f 89/120/106 103/134/106 104/135/106 -f 96/127/107 112/143/107 97/128/107 -f 90/121/108 104/135/108 105/136/108 -f 83/114/109 82/88/109 98/129/109 -f 308/345/110 97/128/110 112/143/110 -f 90/121/111 106/137/111 91/122/111 -f 84/115/112 98/129/112 99/130/112 -f 110/141/113 126/157/113 111/142/113 -f 104/135/114 118/149/114 119/150/114 -f 111/142/115 127/158/115 112/143/115 -f 105/136/116 119/150/116 120/151/116 -f 98/129/117 82/89/117 113/144/117 -f 308/346/118 112/143/118 127/158/118 -f 105/136/119 121/152/119 106/137/119 -f 99/130/120 113/144/120 114/145/120 -f 106/137/121 122/153/121 107/138/121 -f 99/130/122 115/146/122 100/131/122 -f 108/139/123 122/153/123 123/154/123 -f 100/131/124 116/147/124 101/132/124 -f 108/139/125 124/155/125 109/140/125 -f 102/133/126 116/147/126 117/148/126 -f 110/141/127 124/155/127 125/156/127 -f 102/133/128 118/149/128 103/134/128 -f 114/145/129 130/161/129 115/146/129 -f 123/154/130 137/168/130 138/169/130 -f 115/146/131 131/162/131 116/147/131 -f 123/154/132 139/170/132 124/155/132 -f 117/148/133 131/162/133 132/163/133 -f 125/156/134 139/170/134 140/171/134 -f 117/148/135 133/164/135 118/149/135 -f 125/156/136 141/172/136 126/157/136 -f 119/150/137 133/164/137 134/165/137 -f 126/157/138 142/173/138 127/158/138 -f 120/151/139 134/165/139 135/166/139 -f 113/144/140 82/90/140 128/159/140 -f 308/347/141 127/158/141 142/173/141 -f 120/151/142 136/167/142 121/152/142 -f 113/144/143 129/160/143 114/145/143 -f 121/152/144 137/168/144 122/153/144 -f 134/165/145 148/179/145 149/180/145 -f 142/173/146 156/187/146 157/188/146 -f 135/166/147 149/180/147 150/181/147 -f 128/159/148 82/91/148 143/174/148 -f 308/348/149 142/173/149 157/188/149 -f 135/166/150 151/182/150 136/167/150 -f 128/159/151 144/175/151 129/160/151 -f 136/167/152 152/183/152 137/168/152 -f 130/161/153 144/175/153 145/176/153 -f 138/169/154 152/183/154 153/184/154 -f 130/161/155 146/177/155 131/162/155 -f 138/169/156 154/185/156 139/170/156 -f 132/163/157 146/177/157 147/178/157 -f 140/171/158 154/185/158 155/186/158 -f 132/163/159 148/179/159 133/164/159 -f 140/171/160 156/187/160 141/172/160 -f 153/184/161 167/198/161 168/199/161 -f 145/176/162 161/192/162 146/177/162 -f 153/184/163 169/200/163 154/185/163 -f 147/178/164 161/192/164 162/193/164 -f 155/186/165 169/200/165 170/201/165 -f 147/178/166 163/194/166 148/179/166 -f 155/186/167 171/202/167 156/187/167 -f 149/180/168 163/194/168 164/195/168 -f 156/187/169 172/203/169 157/188/169 -f 150/181/170 164/195/170 165/196/170 -f 143/174/171 82/92/171 158/189/171 -f 308/349/172 157/188/172 172/203/172 -f 150/181/173 166/197/173 151/182/173 -f 143/174/174 159/190/174 144/175/174 -f 151/182/175 167/198/175 152/183/175 -f 145/176/176 159/190/176 160/191/176 -f 172/203/177 186/217/177 187/218/177 -f 165/196/178 179/210/178 180/211/178 -f 158/189/179 82/93/179 173/204/179 -f 308/350/180 172/203/180 187/218/180 -f 165/196/181 181/212/181 166/197/181 -f 158/189/182 174/205/182 159/190/182 -f 166/197/183 182/213/183 167/198/183 -f 159/190/184 175/206/184 160/191/184 -f 168/199/185 182/213/185 183/214/185 -f 160/191/186 176/207/186 161/192/186 -f 168/199/187 184/215/187 169/200/187 -f 162/193/188 176/207/188 177/208/188 -f 169/200/189 185/216/189 170/201/189 -f 162/193/190 178/209/190 163/194/190 -f 171/202/191 185/216/191 186/217/191 -f 164/195/192 178/209/192 179/210/192 -f 175/206/193 191/222/193 176/207/193 -f 183/214/194 199/230/194 184/215/194 -f 177/208/195 191/222/195 192/223/195 -f 185/216/196 199/230/196 200/231/196 -f 177/208/197 193/224/197 178/209/197 -f 185/216/198 201/232/198 186/217/198 -f 179/210/199 193/224/199 194/225/199 -f 186/217/200 202/233/200 187/218/200 -f 180/211/201 194/225/201 195/226/201 -f 173/204/202 82/94/202 188/219/202 -f 308/351/203 187/218/203 202/233/203 -f 180/211/204 196/227/204 181/212/204 -f 174/205/205 188/219/205 189/220/205 -f 181/212/206 197/228/206 182/213/206 -f 175/206/207 189/220/207 190/221/207 -f 183/214/208 197/228/208 198/229/208 -f 195/226/209 209/240/209 210/241/209 -f 188/219/210 82/95/210 203/234/210 -f 308/352/211 202/233/211 217/248/211 -f 195/226/212 211/242/212 196/227/212 -f 188/219/213 204/235/213 189/220/213 -f 196/227/214 212/243/214 197/228/214 -f 189/220/215 205/236/215 190/221/215 -f 198/229/216 212/243/216 213/244/216 -f 190/221/217 206/237/217 191/222/217 -f 198/229/218 214/245/218 199/230/218 -f 192/223/219 206/237/219 207/238/219 -f 200/231/220 214/245/220 215/246/220 -f 192/223/221 208/239/221 193/224/221 -f 200/231/222 216/247/222 201/232/222 -f 194/225/223 208/239/223 209/240/223 -f 201/232/224 217/248/224 202/233/224 -f 213/244/225 229/260/225 214/245/225 -f 207/238/226 221/252/226 222/253/226 -f 215/246/227 229/260/227 230/261/227 -f 207/238/228 223/254/228 208/239/228 -f 215/246/229 231/262/229 216/247/229 -f 209/240/230 223/254/230 224/255/230 -f 216/247/231 232/263/231 217/248/231 -f 210/241/232 224/255/232 225/256/232 -f 203/234/233 82/96/233 218/249/233 -f 308/353/234 217/248/234 232/263/234 -f 210/241/235 226/257/235 211/242/235 -f 203/234/236 219/250/236 204/235/236 -f 211/242/237 227/258/237 212/243/237 -f 204/235/238 220/251/238 205/236/238 -f 213/244/239 227/258/239 228/259/239 -f 205/236/240 221/252/240 206/237/240 -f 308/354/241 232/263/241 247/278/241 -f 225/256/242 241/272/242 226/257/242 -f 218/249/243 234/265/243 219/250/243 -f 226/257/244 242/273/244 227/258/244 -f 220/251/245 234/265/245 235/266/245 -f 228/259/246 242/273/246 243/274/246 -f 220/251/247 236/267/247 221/252/247 -f 228/259/248 244/275/248 229/260/248 -f 222/253/249 236/267/249 237/268/249 -f 230/261/250 244/275/250 245/276/250 -f 222/253/251 238/269/251 223/254/251 -f 230/261/252 246/277/252 231/262/252 -f 224/255/253 238/269/253 239/270/253 -f 232/263/254 246/277/254 247/278/254 -f 225/256/255 239/270/255 240/271/255 -f 218/249/256 82/97/256 233/264/256 -f 245/276/257 259/290/257 260/291/257 -f 237/268/258 253/284/258 238/269/258 -f 245/276/259 261/292/259 246/277/259 -f 239/270/260 253/284/260 254/285/260 -f 246/277/261 262/293/261 247/278/261 -f 240/271/262 254/285/262 255/286/262 -f 233/264/263 82/98/263 248/279/263 -f 308/355/264 247/278/264 262/293/264 -f 240/271/265 256/287/265 241/272/265 -f 233/264/266 249/280/266 234/265/266 -f 241/272/267 257/288/267 242/273/267 -f 234/265/268 250/281/268 235/266/268 -f 243/274/269 257/288/269 258/289/269 -f 235/266/270 251/282/270 236/267/270 -f 243/274/271 259/290/271 244/275/271 -f 237/268/272 251/282/272 252/283/272 -f 249/280/273 263/294/273 264/295/273 -f 256/287/274 272/303/274 257/288/274 -f 249/280/275 265/296/275 250/281/275 -f 258/289/276 272/303/276 273/304/276 -f 250/281/277 266/297/277 251/282/277 -f 258/289/278 274/305/278 259/290/278 -f 252/283/279 266/297/279 267/298/279 -f 260/291/280 274/305/280 275/306/280 -f 252/283/281 268/299/281 253/284/281 -f 260/291/282 276/307/282 261/292/282 -f 254/285/283 268/299/283 269/300/283 -f 261/292/284 277/308/284 262/293/284 -f 255/286/285 269/300/285 270/301/285 -f 248/279/286 82/99/286 263/294/286 -f 308/356/287 262/293/287 277/308/287 -f 255/286/288 271/302/288 256/287/288 -f 267/298/289 283/314/289 268/299/289 -f 275/306/290 291/322/290 276/307/290 -f 269/300/291 283/314/291 284/315/291 -f 277/308/292 291/322/292 292/323/292 -f 270/301/293 284/315/293 285/316/293 -f 263/294/294 82/100/294 278/309/294 -f 308/357/295 277/308/295 292/323/295 -f 270/301/296 286/317/296 271/302/296 -f 264/295/297 278/309/297 279/310/297 -f 271/302/298 287/318/298 272/303/298 -f 264/295/299 280/311/299 265/296/299 -f 273/304/300 287/318/300 288/319/300 -f 265/296/301 281/312/301 266/297/301 -f 273/304/302 289/320/302 274/305/302 -f 267/298/303 281/312/303 282/313/303 -f 275/306/304 289/320/304 290/321/304 -f 286/317/305 302/333/305 287/318/305 -f 279/310/306 295/326/306 280/311/306 -f 288/319/307 302/333/307 303/334/307 -f 280/311/308 296/327/308 281/312/308 -f 288/319/309 304/335/309 289/320/309 -f 282/313/310 296/327/310 297/328/310 -f 290/321/311 304/335/311 305/336/311 -f 282/313/312 298/329/312 283/314/312 -f 290/321/313 306/337/313 291/322/313 -f 284/315/314 298/329/314 299/330/314 -f 292/323/315 306/337/315 307/338/315 -f 285/316/316 299/330/316 300/331/316 -f 278/309/317 82/101/317 293/324/317 -f 308/358/318 292/323/318 307/338/318 -f 285/316/319 301/332/319 286/317/319 -f 278/309/320 294/325/320 279/310/320 -f 305/336/321 322/384/321 306/337/321 -f 299/330/322 314/376/322 315/377/322 -f 306/337/323 323/385/323 307/338/323 -f 300/331/324 315/377/324 316/378/324 -f 293/324/325 82/102/325 309/371/325 -f 308/359/326 307/338/326 323/385/326 -f 300/331/327 317/379/327 301/332/327 -f 293/324/328 310/372/328 294/325/328 -f 301/332/329 318/380/329 302/333/329 -f 294/325/330 311/373/330 295/326/330 -f 303/334/331 318/380/331 319/381/331 -f 295/326/332 312/374/332 296/327/332 -f 303/334/333 320/382/333 304/335/333 -f 297/328/334 312/374/334 313/375/334 -f 305/336/335 320/382/335 321/383/335 -f 297/328/336 314/376/336 298/329/336 -f 310/372/337 326/388/337 311/373/337 -f 319/381/338 333/395/338 334/396/338 -f 311/373/339 327/389/339 312/374/339 -f 319/381/340 335/397/340 320/382/340 -f 312/374/341 328/390/341 313/375/341 -f 321/383/342 335/397/342 336/398/342 -f 313/375/343 329/391/343 314/376/343 -f 321/383/344 337/399/344 322/384/344 -f 315/377/345 329/391/345 330/392/345 -f 322/384/346 338/400/346 323/385/346 -f 316/378/347 330/392/347 331/393/347 -f 309/371/348 82/103/348 324/386/348 -f 308/360/349 323/385/349 338/400/349 -f 316/378/350 332/394/350 317/379/350 -f 309/371/351 325/387/351 310/372/351 -f 317/379/352 333/395/352 318/380/352 -f 330/392/353 344/406/353 345/407/353 -f 337/399/354 353/415/354 338/400/354 -f 331/393/355 345/407/355 346/408/355 -f 324/386/356 82/104/356 339/401/356 -f 308/361/357 338/400/357 353/415/357 -f 331/393/358 347/409/358 332/394/358 -f 324/386/359 340/402/359 325/387/359 -f 332/394/360 348/410/360 333/395/360 -f 325/387/361 341/403/361 326/388/361 -f 334/396/362 348/410/362 349/411/362 -f 326/388/363 342/404/363 327/389/363 -f 334/396/364 350/412/364 335/397/364 -f 328/390/365 342/404/365 343/405/365 -f 336/398/366 350/412/366 351/413/366 -f 328/390/367 344/406/367 329/391/367 -f 336/398/368 352/414/368 337/399/368 -f 349/411/369 363/434/369 364/436/369 -f 341/403/370 357/422/370 342/404/370 -f 349/411/371 365/438/371 350/412/371 -f 343/405/372 357/422/372 358/424/372 -f 351/413/373 365/438/373 366/440/373 -f 343/405/374 359/426/374 344/406/374 -f 351/413/375 367/442/375 352/414/375 -f 345/407/376 359/426/376 360/428/376 -f 352/414/377 368/445/377 353/415/377 -f 346/408/378 360/428/378 361/430/378 -f 339/401/379 82/105/379 354/416/379 -f 308/362/380 353/415/380 368/445/380 -f 346/408/381 362/432/381 347/409/381 -f 339/401/382 355/418/382 340/402/382 -f 347/409/383 363/434/383 348/410/383 -f 341/403/384 355/418/384 356/420/384 -f 367/443/385 383/460/385 368/444/385 -f 361/431/386 375/452/386 376/453/386 -f 354/417/387 82/106/387 369/446/387 -f 308/363/388 368/444/388 383/460/388 -f 361/431/389 377/454/389 362/433/389 -f 354/417/390 370/447/390 355/419/390 -f 362/433/391 378/455/391 363/435/391 -f 356/421/392 370/447/392 371/448/392 -f 364/437/393 378/455/393 379/456/393 -f 356/421/394 372/449/394 357/423/394 -f 364/437/395 380/457/395 365/439/395 -f 358/425/396 372/449/396 373/450/396 -f 366/441/397 380/457/397 381/458/397 -f 358/425/398 374/451/398 359/427/398 -f 366/441/399 382/459/399 367/443/399 -f 360/429/400 374/451/400 375/452/400 -f 379/456/401 395/472/401 380/457/401 -f 373/450/402 387/464/402 388/465/402 -f 381/458/403 395/472/403 396/473/403 -f 373/450/404 389/466/404 374/451/404 -f 381/458/405 397/474/405 382/459/405 -f 375/452/406 389/466/406 390/467/406 -f 382/459/407 398/475/407 383/460/407 -f 376/453/408 390/467/408 391/468/408 -f 369/446/409 82/107/409 384/461/409 -f 308/364/410 383/460/410 398/475/410 -f 376/453/411 392/469/411 377/454/411 -f 369/446/412 385/462/412 370/447/412 -f 377/454/413 393/470/413 378/455/413 -f 371/448/414 385/462/414 386/463/414 -f 379/456/415 393/470/415 394/471/415 -f 371/448/416 387/464/416 372/449/416 -f 384/461/417 82/108/417 399/476/417 -f 308/365/418 398/475/418 413/490/418 -f 391/468/419 407/484/419 392/469/419 -f 385/462/420 399/476/420 400/477/420 -f 392/469/421 408/485/421 393/470/421 -f 385/462/422 401/478/422 386/463/422 -f 394/471/423 408/485/423 409/486/423 -f 386/463/424 402/479/424 387/464/424 -f 394/471/425 410/487/425 395/472/425 -f 388/465/426 402/479/426 403/480/426 -f 396/473/427 410/487/427 411/488/427 -f 388/465/428 404/481/428 389/466/428 -f 397/474/429 411/488/429 412/489/429 -f 390/467/430 404/481/430 405/482/430 -f 397/474/431 413/490/431 398/475/431 -f 391/468/432 405/482/432 406/483/432 -f 403/480/433 417/494/433 418/495/433 -f 411/488/434 425/502/434 426/503/434 -f 403/480/435 419/496/435 404/481/435 -f 411/488/436 427/504/436 412/489/436 -f 405/482/437 419/496/437 420/497/437 -f 412/489/438 428/505/438 413/490/438 -f 406/483/439 420/497/439 421/498/439 -f 399/476/440 82/109/440 414/491/440 -f 308/366/441 413/490/441 428/505/441 -f 406/483/442 422/499/442 407/484/442 -f 399/476/443 415/492/443 400/477/443 -f 407/484/444 423/500/444 408/485/444 -f 401/478/445 415/492/445 416/493/445 -f 409/486/446 423/500/446 424/501/446 -f 401/478/447 417/494/447 402/479/447 -f 409/486/448 425/502/448 410/487/448 -f 421/498/449 437/514/449 422/499/449 -f 414/491/450 430/507/450 415/492/450 -f 422/499/451 438/515/451 423/500/451 -f 416/493/452 430/507/452 431/508/452 -f 424/501/453 438/515/453 439/516/453 -f 416/493/454 432/509/454 417/494/454 -f 424/501/455 440/517/455 425/502/455 -f 418/495/456 432/509/456 433/510/456 -f 426/503/457 440/517/457 441/518/457 -f 418/495/458 434/511/458 419/496/458 -f 426/503/459 442/519/459 427/504/459 -f 420/497/460 434/511/460 435/512/460 -f 427/504/461 443/520/461 428/505/461 -f 421/498/462 435/512/462 436/513/462 -f 414/491/463 82/110/463 429/506/463 -f 308/367/464 428/505/464 443/520/464 -f 441/518/465 455/532/465 456/533/465 -f 433/510/466 449/526/466 434/511/466 -f 441/518/467 457/534/467 442/519/467 -f 435/512/468 449/526/468 450/527/468 -f 442/519/469 458/535/469 443/520/469 -f 436/513/470 450/527/470 451/528/470 -f 429/506/471 82/111/471 444/521/471 -f 308/368/472 443/520/472 458/535/472 -f 436/513/473 452/529/473 437/514/473 -f 430/507/474 444/521/474 445/522/474 -f 437/514/475 453/530/475 438/515/475 -f 430/507/476 446/523/476 431/508/476 -f 439/516/477 453/530/477 454/531/477 -f 431/508/478 447/524/478 432/509/478 -f 439/516/479 455/532/479 440/517/479 -f 433/510/480 447/524/480 448/525/480 -f 444/521/481 460/537/481 445/522/481 -f 452/529/482 468/545/482 453/530/482 -f 446/523/483 460/537/483 461/538/483 -f 454/531/484 468/545/484 469/546/484 -f 446/523/485 462/539/485 447/524/485 -f 454/531/486 470/547/486 455/532/486 -f 448/525/487 462/539/487 463/540/487 -f 456/533/488 470/547/488 471/548/488 -f 448/525/489 464/541/489 449/526/489 -f 456/533/490 472/549/490 457/534/490 -f 450/527/491 464/541/491 465/542/491 -f 458/535/492 472/549/492 473/550/492 -f 451/528/493 465/542/493 466/543/493 -f 444/521/494 82/112/494 459/536/494 -f 308/369/495 458/535/495 473/550/495 -f 451/528/496 467/544/496 452/529/496 -f 464/541/497 2/2/497 477/554/497 -f 471/548/498 481/558/498 472/549/498 -f 465/542/499 477/554/499 3/3/499 -f 472/549/500 482/559/500 473/550/500 -f 466/543/501 3/3/501 4/4/501 -f 459/536/502 82/113/502 474/551/502 -f 308/370/503 473/550/503 482/559/503 -f 466/543/504 5/5/504 467/544/504 -f 460/537/505 474/551/505 475/552/505 -f 467/544/506 478/555/506 468/545/506 -f 461/538/507 475/552/507 1/1/507 -f 468/545/508 6/6/508 469/546/508 -f 462/539/509 1/1/509 476/553/509 -f 469/546/510 479/556/510 470/547/510 -f 463/540/511 476/553/511 2/2/511 -f 471/548/512 479/556/512 480/557/512 -f 479/556/1 18/18/1 19/19/1 -f 477/554/2 2/2/2 11/11/2 -f 480/557/3 19/19/3 20/20/3 -f 3/3/4 477/554/4 12/12/4 -f 481/558/5 20/20/5 21/21/5 -f 3/3/513 13/13/513 14/14/513 -f 4/4/514 14/14/514 15/15/514 -f 475/552/10 474/551/10 7/7/10 -f 5/5/11 15/15/11 16/16/11 -f 1/1/12 475/552/12 8/8/12 -f 478/555/13 16/16/13 17/17/13 -f 476/553/14 1/1/14 9/9/14 -f 6/6/15 17/17/15 18/18/15 -f 2/2/16 476/553/16 10/10/16 -f 17/17/17 32/32/17 33/33/17 -f 10/10/18 25/25/18 26/26/18 -f 19/19/19 18/18/19 33/33/19 -f 11/11/20 26/26/20 27/27/20 -f 20/20/21 19/19/21 34/34/21 -f 13/13/22 12/12/22 27/27/22 -f 20/20/23 35/35/23 36/36/23 -f 13/13/24 28/28/24 29/29/24 -f 14/14/27 29/29/27 30/30/27 -f 7/7/28 22/22/28 23/23/28 -f 15/15/29 30/30/29 31/31/29 -f 8/8/30 23/23/30 24/24/30 -f 16/16/31 31/31/31 32/32/31 -f 9/9/32 24/24/32 25/25/32 -f 30/30/35 29/29/35 44/44/35 -f 22/22/36 37/37/36 38/38/36 -f 30/30/37 45/45/37 46/46/37 -f 23/23/515 38/38/515 39/39/515 -f 32/32/39 31/31/39 46/46/39 -f 24/24/40 39/39/40 40/40/40 -f 33/33/41 32/32/41 47/47/41 -f 25/25/42 40/40/42 41/41/42 -f 34/34/43 33/33/43 48/48/43 -f 26/26/44 41/41/44 42/42/44 -f 34/34/516 49/49/516 50/50/516 -f 27/27/46 42/42/46 43/43/46 -f 35/35/47 50/50/47 51/51/47 -f 28/28/48 43/43/48 44/44/48 -f 40/40/49 55/55/49 56/56/49 -f 48/48/50 63/63/50 64/64/50 -f 41/41/51 56/56/51 57/57/51 -f 49/49/52 64/64/52 65/65/52 -f 43/43/53 42/42/53 57/57/53 -f 50/50/54 65/65/54 66/66/54 -f 44/44/55 43/43/55 58/58/55 -f 44/44/58 59/59/58 60/60/58 -f 37/37/59 52/52/59 53/53/59 -f 45/45/60 60/60/60 61/61/60 -f 38/38/61 53/53/61 54/54/61 -f 47/47/62 46/46/62 61/61/62 -f 39/39/63 54/54/63 55/55/63 -f 47/47/64 62/62/64 63/63/64 -f 59/59/65 74/74/65 75/75/65 -f 52/52/66 67/67/66 68/68/66 -f 60/60/67 75/75/67 76/76/67 -f 53/53/68 68/68/68 69/69/68 -f 62/62/69 61/61/69 76/76/69 -f 54/54/70 69/69/70 70/70/70 -f 62/62/71 77/77/71 78/78/71 -f 56/56/72 55/55/72 70/70/72 -f 63/63/73 78/78/73 79/79/73 -f 56/56/74 71/71/74 72/72/74 -f 65/65/75 64/64/75 79/79/75 -f 58/58/76 57/57/76 72/72/76 -f 65/65/517 80/80/517 81/81/517 -f 59/59/78 58/58/78 73/73/78 -f 78/78/81 94/125/81 95/126/81 -f 71/71/82 87/118/82 88/119/82 -f 79/79/83 95/126/83 96/127/83 -f 73/73/84 72/72/84 88/119/84 -f 81/81/85 80/80/85 96/127/85 -f 74/74/86 73/73/86 89/120/86 -f 74/74/89 90/121/89 91/122/89 -f 67/67/90 83/114/90 84/115/90 -f 75/75/91 91/122/91 92/123/91 -f 68/68/92 84/115/92 85/116/92 -f 77/77/93 76/76/93 92/123/93 -f 69/69/94 85/116/94 86/117/94 -f 77/77/95 93/124/95 94/125/95 -f 71/71/96 70/70/96 86/117/96 -f 91/122/97 106/137/97 107/138/97 -f 84/115/98 99/130/98 100/131/98 -f 93/124/99 92/123/99 107/138/99 -f 85/116/100 100/131/100 101/132/100 -f 93/124/101 108/139/101 109/140/101 -f 87/118/102 86/117/102 101/132/102 -f 95/126/103 94/125/103 109/140/103 -f 87/118/104 102/133/104 103/134/104 -f 96/127/105 95/126/105 110/141/105 -f 89/120/106 88/119/106 103/134/106 -f 96/127/107 111/142/107 112/143/107 -f 90/121/108 89/120/108 104/135/108 -f 90/121/111 105/136/111 106/137/111 -f 84/115/112 83/114/112 98/129/112 -f 110/141/113 125/156/113 126/157/113 -f 104/135/114 103/134/114 118/149/114 -f 111/142/115 126/157/115 127/158/115 -f 105/136/116 104/135/116 119/150/116 -f 105/136/119 120/151/119 121/152/119 -f 99/130/120 98/129/120 113/144/120 -f 106/137/121 121/152/121 122/153/121 -f 99/130/122 114/145/122 115/146/122 -f 108/139/123 107/138/123 122/153/123 -f 100/131/124 115/146/124 116/147/124 -f 108/139/125 123/154/125 124/155/125 -f 102/133/126 101/132/126 116/147/126 -f 110/141/127 109/140/127 124/155/127 -f 102/133/128 117/148/128 118/149/128 -f 114/145/129 129/160/129 130/161/129 -f 123/154/130 122/153/130 137/168/130 -f 115/146/131 130/161/131 131/162/131 -f 123/154/132 138/169/132 139/170/132 -f 117/148/133 116/147/133 131/162/133 -f 125/156/134 124/155/134 139/170/134 -f 117/148/135 132/163/135 133/164/135 -f 125/156/136 140/171/136 141/172/136 -f 119/150/137 118/149/137 133/164/137 -f 126/157/138 141/172/138 142/173/138 -f 120/151/139 119/150/139 134/165/139 -f 120/151/142 135/166/142 136/167/142 -f 113/144/143 128/159/143 129/160/143 -f 121/152/144 136/167/144 137/168/144 -f 134/165/145 133/164/145 148/179/145 -f 142/173/146 141/172/146 156/187/146 -f 135/166/147 134/165/147 149/180/147 -f 135/166/150 150/181/150 151/182/150 -f 128/159/151 143/174/151 144/175/151 -f 136/167/152 151/182/152 152/183/152 -f 130/161/153 129/160/153 144/175/153 -f 138/169/154 137/168/154 152/183/154 -f 130/161/155 145/176/155 146/177/155 -f 138/169/156 153/184/156 154/185/156 -f 132/163/157 131/162/157 146/177/157 -f 140/171/158 139/170/158 154/185/158 -f 132/163/159 147/178/159 148/179/159 -f 140/171/160 155/186/160 156/187/160 -f 153/184/161 152/183/161 167/198/161 -f 145/176/162 160/191/162 161/192/162 -f 153/184/163 168/199/163 169/200/163 -f 147/178/164 146/177/164 161/192/164 -f 155/186/165 154/185/165 169/200/165 -f 147/178/166 162/193/166 163/194/166 -f 155/186/518 170/201/518 171/202/518 -f 149/180/168 148/179/168 163/194/168 -f 156/187/169 171/202/169 172/203/169 -f 150/181/170 149/180/170 164/195/170 -f 150/181/173 165/196/173 166/197/173 -f 143/174/519 158/189/519 159/190/519 -f 151/182/175 166/197/175 167/198/175 -f 145/176/520 144/175/520 159/190/520 -f 172/203/177 171/202/177 186/217/177 -f 165/196/178 164/195/178 179/210/178 -f 165/196/181 180/211/181 181/212/181 -f 158/189/182 173/204/182 174/205/182 -f 166/197/183 181/212/183 182/213/183 -f 159/190/184 174/205/184 175/206/184 -f 168/199/185 167/198/185 182/213/185 -f 160/191/186 175/206/186 176/207/186 -f 168/199/187 183/214/187 184/215/187 -f 162/193/188 161/192/188 176/207/188 -f 169/200/189 184/215/189 185/216/189 -f 162/193/190 177/208/190 178/209/190 -f 171/202/191 170/201/191 185/216/191 -f 164/195/192 163/194/192 178/209/192 -f 175/206/193 190/221/193 191/222/193 -f 183/214/194 198/229/194 199/230/194 -f 177/208/195 176/207/195 191/222/195 -f 185/216/196 184/215/196 199/230/196 -f 177/208/197 192/223/197 193/224/197 -f 185/216/198 200/231/198 201/232/198 -f 179/210/199 178/209/199 193/224/199 -f 186/217/200 201/232/200 202/233/200 -f 180/211/201 179/210/201 194/225/201 -f 180/211/204 195/226/204 196/227/204 -f 174/205/205 173/204/205 188/219/205 -f 181/212/206 196/227/206 197/228/206 -f 175/206/207 174/205/207 189/220/207 -f 183/214/208 182/213/208 197/228/208 -f 195/226/209 194/225/209 209/240/209 -f 195/226/212 210/241/212 211/242/212 -f 188/219/213 203/234/213 204/235/213 -f 196/227/214 211/242/214 212/243/214 -f 189/220/215 204/235/215 205/236/215 -f 198/229/216 197/228/216 212/243/216 -f 190/221/217 205/236/217 206/237/217 -f 198/229/218 213/244/218 214/245/218 -f 192/223/219 191/222/219 206/237/219 -f 200/231/220 199/230/220 214/245/220 -f 192/223/221 207/238/221 208/239/221 -f 200/231/521 215/246/521 216/247/521 -f 194/225/223 193/224/223 208/239/223 -f 201/232/224 216/247/224 217/248/224 -f 213/244/225 228/259/225 229/260/225 -f 207/238/226 206/237/226 221/252/226 -f 215/246/227 214/245/227 229/260/227 -f 207/238/228 222/253/228 223/254/228 -f 215/246/229 230/261/229 231/262/229 -f 209/240/230 208/239/230 223/254/230 -f 216/247/231 231/262/231 232/263/231 -f 210/241/232 209/240/232 224/255/232 -f 210/241/235 225/256/235 226/257/235 -f 203/234/236 218/249/236 219/250/236 -f 211/242/237 226/257/237 227/258/237 -f 204/235/238 219/250/238 220/251/238 -f 213/244/239 212/243/239 227/258/239 -f 205/236/240 220/251/240 221/252/240 -f 225/256/242 240/271/242 241/272/242 -f 218/249/243 233/264/243 234/265/243 -f 226/257/244 241/272/244 242/273/244 -f 220/251/245 219/250/245 234/265/245 -f 228/259/246 227/258/246 242/273/246 -f 220/251/247 235/266/247 236/267/247 -f 228/259/248 243/274/248 244/275/248 -f 222/253/249 221/252/249 236/267/249 -f 230/261/250 229/260/250 244/275/250 -f 222/253/251 237/268/251 238/269/251 -f 230/261/252 245/276/252 246/277/252 -f 224/255/253 223/254/253 238/269/253 -f 232/263/254 231/262/254 246/277/254 -f 225/256/255 224/255/255 239/270/255 -f 245/276/257 244/275/257 259/290/257 -f 237/268/258 252/283/258 253/284/258 -f 245/276/259 260/291/259 261/292/259 -f 239/270/260 238/269/260 253/284/260 -f 246/277/261 261/292/261 262/293/261 -f 240/271/522 239/270/522 254/285/522 -f 240/271/523 255/286/523 256/287/523 -f 233/264/266 248/279/266 249/280/266 -f 241/272/267 256/287/267 257/288/267 -f 234/265/268 249/280/268 250/281/268 -f 243/274/269 242/273/269 257/288/269 -f 235/266/270 250/281/270 251/282/270 -f 243/274/271 258/289/271 259/290/271 -f 237/268/272 236/267/272 251/282/272 -f 249/280/273 248/279/273 263/294/273 -f 256/287/274 271/302/274 272/303/274 -f 249/280/275 264/295/275 265/296/275 -f 258/289/276 257/288/276 272/303/276 -f 250/281/277 265/296/277 266/297/277 -f 258/289/278 273/304/278 274/305/278 -f 252/283/279 251/282/279 266/297/279 -f 260/291/280 259/290/280 274/305/280 -f 252/283/281 267/298/281 268/299/281 -f 260/291/282 275/306/282 276/307/282 -f 254/285/283 253/284/283 268/299/283 -f 261/292/284 276/307/284 277/308/284 -f 255/286/285 254/285/285 269/300/285 -f 255/286/288 270/301/288 271/302/288 -f 267/298/289 282/313/289 283/314/289 -f 275/306/524 290/321/524 291/322/524 -f 269/300/291 268/299/291 283/314/291 -f 277/308/292 276/307/292 291/322/292 -f 270/301/293 269/300/293 284/315/293 -f 270/301/296 285/316/296 286/317/296 -f 264/295/297 263/294/297 278/309/297 -f 271/302/298 286/317/298 287/318/298 -f 264/295/525 279/310/525 280/311/525 -f 273/304/300 272/303/300 287/318/300 -f 265/296/301 280/311/301 281/312/301 -f 273/304/302 288/319/302 289/320/302 -f 267/298/303 266/297/303 281/312/303 -f 275/306/304 274/305/304 289/320/304 -f 286/317/305 301/332/305 302/333/305 -f 279/310/306 294/325/306 295/326/306 -f 288/319/307 287/318/307 302/333/307 -f 280/311/308 295/326/308 296/327/308 -f 288/319/309 303/334/309 304/335/309 -f 282/313/310 281/312/310 296/327/310 -f 290/321/311 289/320/311 304/335/311 -f 282/313/312 297/328/312 298/329/312 -f 290/321/313 305/336/313 306/337/313 -f 284/315/314 283/314/314 298/329/314 -f 292/323/315 291/322/315 306/337/315 -f 285/316/316 284/315/316 299/330/316 -f 285/316/319 300/331/319 301/332/319 -f 278/309/320 293/324/320 294/325/320 -f 305/336/321 321/383/321 322/384/321 -f 299/330/322 298/329/322 314/376/322 -f 306/337/526 322/384/526 323/385/526 -f 300/331/324 299/330/324 315/377/324 -f 300/331/327 316/378/327 317/379/327 -f 293/324/328 309/371/328 310/372/328 -f 301/332/329 317/379/329 318/380/329 -f 294/325/330 310/372/330 311/373/330 -f 303/334/331 302/333/331 318/380/331 -f 295/326/332 311/373/332 312/374/332 -f 303/334/333 319/381/333 320/382/333 -f 297/328/334 296/327/334 312/374/334 -f 305/336/335 304/335/335 320/382/335 -f 297/328/336 313/375/336 314/376/336 -f 310/372/337 325/387/337 326/388/337 -f 319/381/338 318/380/338 333/395/338 -f 311/373/339 326/388/339 327/389/339 -f 319/381/340 334/396/340 335/397/340 -f 312/374/341 327/389/341 328/390/341 -f 321/383/342 320/382/342 335/397/342 -f 313/375/343 328/390/343 329/391/343 -f 321/383/527 336/398/527 337/399/527 -f 315/377/345 314/376/345 329/391/345 -f 322/384/346 337/399/346 338/400/346 -f 316/378/347 315/377/347 330/392/347 -f 316/378/350 331/393/350 332/394/350 -f 309/371/351 324/386/351 325/387/351 -f 317/379/352 332/394/352 333/395/352 -f 330/392/353 329/391/353 344/406/353 -f 337/399/354 352/414/354 353/415/354 -f 331/393/355 330/392/355 345/407/355 -f 331/393/358 346/408/358 347/409/358 -f 324/386/359 339/401/359 340/402/359 -f 332/394/360 347/409/360 348/410/360 -f 325/387/361 340/402/361 341/403/361 -f 334/396/362 333/395/362 348/410/362 -f 326/388/363 341/403/363 342/404/363 -f 334/396/364 349/411/364 350/412/364 -f 328/390/365 327/389/365 342/404/365 -f 336/398/366 335/397/366 350/412/366 -f 328/390/367 343/405/367 344/406/367 -f 336/398/368 351/413/368 352/414/368 -f 349/411/369 348/410/369 363/434/369 -f 341/403/370 356/420/370 357/422/370 -f 349/411/371 364/436/371 365/438/371 -f 343/405/372 342/404/372 357/422/372 -f 351/413/373 350/412/373 365/438/373 -f 343/405/374 358/424/374 359/426/374 -f 351/413/375 366/440/375 367/442/375 -f 345/407/376 344/406/376 359/426/376 -f 352/414/377 367/442/377 368/445/377 -f 346/408/528 345/407/528 360/428/528 -f 346/408/529 361/430/529 362/432/529 -f 339/401/382 354/416/382 355/418/382 -f 347/409/383 362/432/383 363/434/383 -f 341/403/384 340/402/384 355/418/384 -f 367/443/385 382/459/385 383/460/385 -f 361/431/530 360/429/530 375/452/530 -f 361/431/531 376/453/531 377/454/531 -f 354/417/390 369/446/390 370/447/390 -f 362/433/391 377/454/391 378/455/391 -f 356/421/392 355/419/392 370/447/392 -f 364/437/393 363/435/393 378/455/393 -f 356/421/394 371/448/394 372/449/394 -f 364/437/395 379/456/395 380/457/395 -f 358/425/396 357/423/396 372/449/396 -f 366/441/397 365/439/397 380/457/397 -f 358/425/398 373/450/398 374/451/398 -f 366/441/399 381/458/399 382/459/399 -f 360/429/400 359/427/400 374/451/400 -f 379/456/401 394/471/401 395/472/401 -f 373/450/402 372/449/402 387/464/402 -f 381/458/403 380/457/403 395/472/403 -f 373/450/404 388/465/404 389/466/404 -f 381/458/405 396/473/405 397/474/405 -f 375/452/406 374/451/406 389/466/406 -f 382/459/407 397/474/407 398/475/407 -f 376/453/408 375/452/408 390/467/408 -f 376/453/411 391/468/411 392/469/411 -f 369/446/412 384/461/412 385/462/412 -f 377/454/413 392/469/413 393/470/413 -f 371/448/414 370/447/414 385/462/414 -f 379/456/415 378/455/415 393/470/415 -f 371/448/416 386/463/416 387/464/416 -f 391/468/419 406/483/419 407/484/419 -f 385/462/420 384/461/420 399/476/420 -f 392/469/421 407/484/421 408/485/421 -f 385/462/422 400/477/422 401/478/422 -f 394/471/423 393/470/423 408/485/423 -f 386/463/424 401/478/424 402/479/424 -f 394/471/425 409/486/425 410/487/425 -f 388/465/426 387/464/426 402/479/426 -f 396/473/427 395/472/427 410/487/427 -f 388/465/428 403/480/428 404/481/428 -f 397/474/429 396/473/429 411/488/429 -f 390/467/430 389/466/430 404/481/430 -f 397/474/431 412/489/431 413/490/431 -f 391/468/432 390/467/432 405/482/432 -f 403/480/433 402/479/433 417/494/433 -f 411/488/434 410/487/434 425/502/434 -f 403/480/435 418/495/435 419/496/435 -f 411/488/436 426/503/436 427/504/436 -f 405/482/437 404/481/437 419/496/437 -f 412/489/438 427/504/438 428/505/438 -f 406/483/439 405/482/439 420/497/439 -f 406/483/442 421/498/442 422/499/442 -f 399/476/443 414/491/443 415/492/443 -f 407/484/444 422/499/444 423/500/444 -f 401/478/445 400/477/445 415/492/445 -f 409/486/446 408/485/446 423/500/446 -f 401/478/447 416/493/447 417/494/447 -f 409/486/448 424/501/448 425/502/448 -f 421/498/449 436/513/449 437/514/449 -f 414/491/450 429/506/450 430/507/450 -f 422/499/451 437/514/451 438/515/451 -f 416/493/452 415/492/452 430/507/452 -f 424/501/453 423/500/453 438/515/453 -f 416/493/454 431/508/454 432/509/454 -f 424/501/455 439/516/455 440/517/455 -f 418/495/456 417/494/456 432/509/456 -f 426/503/457 425/502/457 440/517/457 -f 418/495/458 433/510/458 434/511/458 -f 426/503/459 441/518/459 442/519/459 -f 420/497/460 419/496/460 434/511/460 -f 427/504/461 442/519/461 443/520/461 -f 421/498/462 420/497/462 435/512/462 -f 441/518/465 440/517/465 455/532/465 -f 433/510/466 448/525/466 449/526/466 -f 441/518/467 456/533/467 457/534/467 -f 435/512/468 434/511/468 449/526/468 -f 442/519/469 457/534/469 458/535/469 -f 436/513/470 435/512/470 450/527/470 -f 436/513/473 451/528/473 452/529/473 -f 430/507/474 429/506/474 444/521/474 -f 437/514/475 452/529/475 453/530/475 -f 430/507/476 445/522/476 446/523/476 -f 439/516/477 438/515/477 453/530/477 -f 431/508/478 446/523/478 447/524/478 -f 439/516/479 454/531/479 455/532/479 -f 433/510/480 432/509/480 447/524/480 -f 444/521/481 459/536/481 460/537/481 -f 452/529/482 467/544/482 468/545/482 -f 446/523/483 445/522/483 460/537/483 -f 454/531/484 453/530/484 468/545/484 -f 446/523/485 461/538/485 462/539/485 -f 454/531/486 469/546/486 470/547/486 -f 448/525/487 447/524/487 462/539/487 -f 456/533/488 455/532/488 470/547/488 -f 448/525/489 463/540/489 464/541/489 -f 456/533/490 471/548/490 472/549/490 -f 450/527/491 449/526/491 464/541/491 -f 458/535/492 457/534/492 472/549/492 -f 451/528/493 450/527/493 465/542/493 -f 451/528/496 466/543/496 467/544/496 -f 464/541/497 463/540/497 2/2/497 -f 471/548/498 480/557/498 481/558/498 -f 465/542/499 464/541/499 477/554/499 -f 472/549/500 481/558/500 482/559/500 -f 466/543/501 465/542/501 3/3/501 -f 466/543/504 4/4/504 5/5/504 -f 460/537/505 459/536/505 474/551/505 -f 467/544/506 5/5/506 478/555/506 -f 461/538/507 460/537/507 475/552/507 -f 468/545/508 478/555/508 6/6/508 -f 462/539/509 461/538/509 1/1/509 -f 469/546/510 6/6/510 479/556/510 -f 463/540/511 462/539/511 476/553/511 -f 471/548/512 470/547/512 479/556/512 From 7906560a2b59de205b20e147d4c1a1839bd66da9 Mon Sep 17 00:00:00 2001 From: hqyswife <126778364+hqyswife@users.noreply.github.com> Date: Thu, 29 Jun 2023 01:08:39 +0800 Subject: [PATCH 18/18] Delete smooth-ball.obj --- scenes/meshes/cornell/smooth-ball.obj | 2486 ------------------------- 1 file changed, 2486 deletions(-) delete mode 100644 scenes/meshes/cornell/smooth-ball.obj diff --git a/scenes/meshes/cornell/smooth-ball.obj b/scenes/meshes/cornell/smooth-ball.obj deleted file mode 100644 index d0fe31f..0000000 --- a/scenes/meshes/cornell/smooth-ball.obj +++ /dev/null @@ -1,2486 +0,0 @@ -# Blender 3.5.1 -# www.blender.org -o Sphere -v 1.832444 2.774141 2.360829 -v 1.832444 2.498241 2.084930 -v 1.832444 2.137761 1.935614 -v 1.832444 1.942671 1.916400 -v 1.832444 1.747581 1.935614 -v 1.832444 1.387101 2.084930 -v 1.870504 2.923456 2.725058 -v 1.907102 2.866550 2.541070 -v 1.940830 2.774141 2.371505 -v 1.970393 2.649778 2.222880 -v 1.994655 2.498241 2.100907 -v 2.012684 2.325355 2.010272 -v 2.023785 2.137761 1.954460 -v 2.027534 1.942671 1.935614 -v 2.023785 1.747581 1.954460 -v 2.012684 1.559988 2.010272 -v 1.994655 1.387101 2.100907 -v 1.970393 1.235564 2.222880 -v 1.940830 1.111202 2.371505 -v 1.907102 1.018792 2.541070 -v 1.870504 0.961886 2.725058 -v 1.907102 2.923456 2.736160 -v 1.978890 2.866550 2.562846 -v 2.045051 2.774141 2.403120 -v 2.103042 2.649778 2.263118 -v 2.150633 2.498241 2.148222 -v 2.185997 2.325355 2.062846 -v 2.207774 2.137761 2.010272 -v 2.215127 1.942671 1.992520 -v 2.207774 1.747581 2.010272 -v 2.185997 1.559988 2.062846 -v 2.150633 1.387101 2.148222 -v 2.103042 1.235564 2.263118 -v 2.045051 1.111202 2.403120 -v 1.978890 1.018792 2.562846 -v 1.907102 0.961886 2.736160 -v 1.940830 2.923456 2.754188 -v 2.045051 2.866550 2.598210 -v 2.141102 2.774141 2.454460 -v 2.225291 2.649778 2.328462 -v 2.294384 2.498241 2.225058 -v 2.345724 2.325355 2.148222 -v 2.377339 2.137761 2.100907 -v 2.388014 1.942671 2.084930 -v 2.377339 1.747581 2.100907 -v 2.345724 1.559988 2.148222 -v 2.294384 1.387101 2.225058 -v 2.225291 1.235564 2.328462 -v 2.141102 1.111202 2.454460 -v 2.045051 1.018792 2.598210 -v 1.940830 0.961886 2.754188 -v 1.970393 2.923456 2.778450 -v 2.103042 2.866550 2.645802 -v 2.225291 2.774141 2.523552 -v 2.332444 2.649778 2.416400 -v 2.420382 2.498241 2.328462 -v 2.485725 2.325355 2.263118 -v 2.525964 2.137761 2.222880 -v 2.539551 1.942671 2.209293 -v 2.525964 1.747581 2.222880 -v 2.485725 1.559988 2.263118 -v 2.420382 1.387101 2.328462 -v 2.332444 1.235564 2.416400 -v 2.225291 1.111202 2.523552 -v 2.103042 1.018792 2.645802 -v 1.970393 0.961886 2.778450 -v 1.994655 2.923456 2.808013 -v 2.150633 2.866550 2.703792 -v 2.294384 2.774141 2.607742 -v 2.420382 2.649778 2.523552 -v 2.523785 2.498241 2.454460 -v 2.600621 2.325355 2.403120 -v 2.647937 2.137761 2.371505 -v 2.663913 1.942671 2.360830 -v 2.647937 1.747581 2.371505 -v 2.600621 1.559988 2.403120 -v 2.523785 1.387101 2.454460 -v 2.420382 1.235564 2.523552 -v 2.294384 1.111202 2.607742 -v 2.150633 1.018792 2.703792 -v 1.994655 0.961886 2.808013 -v 1.832444 2.942671 2.916400 -v 2.012684 2.923456 2.841742 -v 2.185997 2.866550 2.769953 -v 2.345724 2.774141 2.703792 -v 2.485725 2.649778 2.645802 -v 2.600621 2.498241 2.598210 -v 2.685997 2.325355 2.562846 -v 2.738571 2.137761 2.541070 -v 2.756323 1.942671 2.533716 -v 2.738571 1.747581 2.541070 -v 2.685997 1.559988 2.562846 -v 2.600621 1.387101 2.598210 -v 2.485725 1.235564 2.645802 -v 2.345724 1.111202 2.703792 -v 2.185997 1.018792 2.769953 -v 2.012684 0.961886 2.841742 -v 2.023785 2.923456 2.878340 -v 2.207774 2.866550 2.841742 -v 2.377339 2.774141 2.808013 -v 2.525964 2.649778 2.778450 -v 2.647937 2.498241 2.754188 -v 2.738571 2.325355 2.736160 -v 2.794383 2.137761 2.725058 -v 2.813229 1.942671 2.721310 -v 2.794383 1.747581 2.725058 -v 2.738571 1.559988 2.736160 -v 2.647937 1.387101 2.754188 -v 2.525964 1.235564 2.778450 -v 2.377339 1.111202 2.808013 -v 2.207774 1.018792 2.841742 -v 2.023785 0.961886 2.878340 -v 2.027534 2.923456 2.916400 -v 2.215127 2.866550 2.916400 -v 2.388014 2.774141 2.916400 -v 2.539550 2.649778 2.916400 -v 2.663913 2.498241 2.916400 -v 2.756323 2.325355 2.916400 -v 2.813229 2.137761 2.916400 -v 2.832443 1.942671 2.916400 -v 2.813229 1.747581 2.916400 -v 2.756323 1.559988 2.916400 -v 2.663913 1.387101 2.916400 -v 2.539550 1.235564 2.916400 -v 2.388014 1.111202 2.916400 -v 2.215127 1.018792 2.916400 -v 2.027534 0.961886 2.916400 -v 2.023785 2.923456 2.954460 -v 2.207774 2.866550 2.991058 -v 2.377339 2.774141 3.024786 -v 2.525964 2.649778 3.054349 -v 2.647937 2.498241 3.078611 -v 2.738571 2.325355 3.096640 -v 2.794383 2.137761 3.107742 -v 2.813229 1.942671 3.111490 -v 2.794383 1.747581 3.107742 -v 2.738571 1.559988 3.096640 -v 2.647937 1.387101 3.078611 -v 2.525964 1.235564 3.054349 -v 2.377339 1.111202 3.024786 -v 2.207774 1.018792 2.991058 -v 2.023785 0.961886 2.954460 -v 2.012684 2.923456 2.991058 -v 2.185997 2.866550 3.062846 -v 2.345724 2.774141 3.129007 -v 2.485725 2.649778 3.186998 -v 2.600621 2.498241 3.234589 -v 2.685997 2.325355 3.269953 -v 2.738571 2.137761 3.291730 -v 2.756323 1.942671 3.299083 -v 2.738571 1.747581 3.291730 -v 2.685997 1.559988 3.269953 -v 2.600621 1.387101 3.234589 -v 2.485725 1.235564 3.186998 -v 2.345724 1.111202 3.129007 -v 2.185997 1.018792 3.062846 -v 2.012684 0.961886 2.991058 -v 1.994655 2.923456 3.024786 -v 2.150633 2.866550 3.129007 -v 2.294383 2.774141 3.225058 -v 2.420382 2.649778 3.309247 -v 2.523785 2.498241 3.378339 -v 2.600621 2.325355 3.429680 -v 2.647937 2.137761 3.461295 -v 2.663913 1.942671 3.471970 -v 2.647937 1.747581 3.461295 -v 2.600621 1.559988 3.429680 -v 2.523785 1.387101 3.378339 -v 2.420382 1.235564 3.309247 -v 2.294383 1.111202 3.225058 -v 2.150633 1.018792 3.129007 -v 1.994655 0.961886 3.024786 -v 1.970393 2.923456 3.054349 -v 2.103042 2.866550 3.186998 -v 2.225291 2.774141 3.309247 -v 2.332444 2.649778 3.416400 -v 2.420381 2.498241 3.504337 -v 2.485725 2.325355 3.569681 -v 2.525963 2.137761 3.609920 -v 2.539550 1.942671 3.623506 -v 2.525963 1.747581 3.609920 -v 2.485725 1.559988 3.569681 -v 2.420381 1.387101 3.504337 -v 2.332444 1.235564 3.416400 -v 2.225291 1.111202 3.309247 -v 2.103042 1.018792 3.186998 -v 1.970393 0.961886 3.054349 -v 1.940830 2.923456 3.078611 -v 2.045051 2.866550 3.234589 -v 2.141102 2.774141 3.378339 -v 2.225291 2.649778 3.504337 -v 2.294383 2.498241 3.607741 -v 2.345724 2.325355 3.684577 -v 2.377339 2.137761 3.731893 -v 2.388013 1.942671 3.747869 -v 2.377339 1.747581 3.731893 -v 2.345724 1.559988 3.684577 -v 2.294383 1.387101 3.607741 -v 2.225291 1.235564 3.504337 -v 2.141102 1.111202 3.378339 -v 2.045051 1.018792 3.234589 -v 1.940830 0.961886 3.078611 -v 1.907102 2.923456 3.096640 -v 1.978890 2.866550 3.269953 -v 2.045051 2.774141 3.429679 -v 2.103042 2.649778 3.569681 -v 2.150633 2.498241 3.684577 -v 2.185997 2.325355 3.769953 -v 2.207774 2.137761 3.822527 -v 2.215127 1.942671 3.840279 -v 2.207774 1.747581 3.822527 -v 2.185997 1.559988 3.769953 -v 2.150633 1.387101 3.684577 -v 2.103042 1.235564 3.569681 -v 2.045051 1.111202 3.429679 -v 1.978890 1.018792 3.269953 -v 1.907102 0.961886 3.096640 -v 1.870504 2.923456 3.107741 -v 1.907102 2.866550 3.291730 -v 1.940830 2.774141 3.461295 -v 1.970393 2.649778 3.609920 -v 1.994655 2.498241 3.731893 -v 2.012684 2.325355 3.822527 -v 2.023785 2.137761 3.878339 -v 2.027534 1.942671 3.897184 -v 2.023785 1.747581 3.878339 -v 2.012684 1.559988 3.822527 -v 1.994655 1.387101 3.731893 -v 1.970393 1.235564 3.609920 -v 1.940830 1.111202 3.461295 -v 1.907102 1.018792 3.291730 -v 1.870504 0.961886 3.107741 -v 1.832444 2.923456 3.111490 -v 1.832444 2.866550 3.299083 -v 1.832444 2.774141 3.471970 -v 1.832444 2.649778 3.623506 -v 1.832444 2.498241 3.747869 -v 1.832444 2.325355 3.840279 -v 1.832444 2.137761 3.897185 -v 1.832443 1.942671 3.916399 -v 1.832444 1.747581 3.897185 -v 1.832444 1.559988 3.840279 -v 1.832444 1.387101 3.747869 -v 1.832444 1.235564 3.623506 -v 1.832444 1.111202 3.471970 -v 1.832444 1.018792 3.299083 -v 1.832444 0.961886 3.111490 -v 1.794384 2.923456 3.107741 -v 1.757786 2.866550 3.291730 -v 1.724057 2.774141 3.461295 -v 1.694494 2.649778 3.609920 -v 1.670232 2.498241 3.731893 -v 1.652204 2.325355 3.822527 -v 1.641102 2.137761 3.878339 -v 1.637353 1.942671 3.897184 -v 1.641102 1.747581 3.878339 -v 1.652204 1.559988 3.822527 -v 1.670232 1.387101 3.731893 -v 1.694494 1.235564 3.609920 -v 1.724057 1.111202 3.461295 -v 1.757786 1.018792 3.291730 -v 1.794384 0.961886 3.107741 -v 1.757786 2.923456 3.096640 -v 1.685997 2.866550 3.269953 -v 1.619836 2.774141 3.429679 -v 1.561846 2.649778 3.569681 -v 1.514254 2.498241 3.684577 -v 1.478890 2.325355 3.769953 -v 1.457114 2.137761 3.822527 -v 1.449760 1.942671 3.840278 -v 1.457114 1.747581 3.822527 -v 1.478890 1.559988 3.769953 -v 1.514254 1.387101 3.684577 -v 1.561846 1.235564 3.569681 -v 1.619836 1.111202 3.429679 -v 1.685997 1.018792 3.269953 -v 1.757786 0.961886 3.096640 -v 1.724057 2.923456 3.078611 -v 1.619836 2.866550 3.234589 -v 1.523786 2.774141 3.378339 -v 1.439596 2.649778 3.504337 -v 1.370504 2.498241 3.607741 -v 1.319164 2.325355 3.684577 -v 1.287549 2.137761 3.731893 -v 1.276874 1.942671 3.747869 -v 1.287549 1.747581 3.731893 -v 1.319164 1.559988 3.684577 -v 1.370504 1.387101 3.607741 -v 1.439596 1.235564 3.504337 -v 1.523786 1.111202 3.378339 -v 1.619836 1.018792 3.234589 -v 1.724057 0.961886 3.078611 -v 1.694494 2.923456 3.054349 -v 1.561846 2.866550 3.186998 -v 1.439596 2.774141 3.309247 -v 1.332444 2.649778 3.416399 -v 1.244506 2.498241 3.504337 -v 1.179163 2.325355 3.569681 -v 1.138924 2.137761 3.609919 -v 1.125337 1.942671 3.623506 -v 1.138924 1.747581 3.609919 -v 1.179163 1.559988 3.569681 -v 1.244506 1.387101 3.504337 -v 1.332444 1.235564 3.416399 -v 1.439596 1.111202 3.309247 -v 1.561846 1.018792 3.186998 -v 1.694494 0.961886 3.054349 -v 1.832444 0.942671 2.916400 -v 1.670232 2.923456 3.024786 -v 1.514254 2.866550 3.129007 -v 1.370504 2.774141 3.225058 -v 1.244506 2.649778 3.309247 -v 1.141102 2.498241 3.378339 -v 1.064266 2.325355 3.429679 -v 1.016951 2.137761 3.461294 -v 1.000975 1.942671 3.471969 -v 1.016951 1.747581 3.461294 -v 1.064266 1.559988 3.429679 -v 1.141102 1.387101 3.378339 -v 1.244506 1.235564 3.309247 -v 1.370504 1.111202 3.225058 -v 1.514254 1.018792 3.129007 -v 1.670232 0.961886 3.024786 -v 1.652204 2.923456 2.991057 -v 1.478890 2.866550 3.062846 -v 1.319164 2.774141 3.129007 -v 1.179162 2.649778 3.186998 -v 1.064266 2.498241 3.234589 -v 0.978891 2.325355 3.269953 -v 0.926317 2.137761 3.291730 -v 0.908565 1.942671 3.299082 -v 0.926317 1.747581 3.291730 -v 0.978891 1.559988 3.269953 -v 1.064266 1.387101 3.234589 -v 1.179162 1.235564 3.186998 -v 1.319164 1.111202 3.129007 -v 1.478890 1.018792 3.062846 -v 1.652204 0.961886 2.991057 -v 1.641102 2.923456 2.954460 -v 1.457114 2.866550 2.991057 -v 1.287549 2.774141 3.024786 -v 1.138924 2.649778 3.054349 -v 1.016951 2.498241 3.078611 -v 0.926317 2.325355 3.096640 -v 0.870504 2.137761 3.107741 -v 0.851659 1.942671 3.111489 -v 0.870504 1.747581 3.107741 -v 0.926317 1.559988 3.096640 -v 1.016951 1.387101 3.078611 -v 1.138924 1.235564 3.054349 -v 1.287549 1.111202 3.024786 -v 1.457114 1.018792 2.991057 -v 1.641102 0.961886 2.954460 -v 1.637354 2.923456 2.916400 -v 1.449760 2.866550 2.916400 -v 1.276874 2.774141 2.916399 -v 1.125337 2.649778 2.916400 -v 1.000975 2.498241 2.916399 -v 0.908565 2.325355 2.916400 -v 0.851659 2.137761 2.916399 -v 0.832445 1.942671 2.916399 -v 0.851659 1.747581 2.916399 -v 0.908565 1.559988 2.916400 -v 1.000975 1.387101 2.916399 -v 1.125337 1.235564 2.916400 -v 1.276874 1.111202 2.916399 -v 1.449760 1.018792 2.916400 -v 1.637354 0.961886 2.916400 -v 1.641102 2.923456 2.878340 -v 1.457114 2.866550 2.841742 -v 1.287549 2.774141 2.808013 -v 1.138924 2.649778 2.778450 -v 1.016951 2.498241 2.754188 -v 0.926317 2.325355 2.736160 -v 0.870504 2.137761 2.725058 -v 0.851659 1.942671 2.721309 -v 0.870504 1.747581 2.725058 -v 0.926317 1.559988 2.736160 -v 1.016951 1.387101 2.754188 -v 1.138924 1.235564 2.778450 -v 1.287549 1.111202 2.808013 -v 1.457114 1.018792 2.841742 -v 1.641102 0.961886 2.878340 -v 1.652204 2.923456 2.841742 -v 1.478891 2.866550 2.769953 -v 1.319164 2.774141 2.703792 -v 1.179163 2.649778 2.645802 -v 1.064266 2.498241 2.598210 -v 0.978891 2.325355 2.562846 -v 0.926317 2.137761 2.541070 -v 0.908565 1.942671 2.533716 -v 0.926317 1.747581 2.541070 -v 0.978891 1.559988 2.562846 -v 1.064266 1.387101 2.598210 -v 1.179163 1.235564 2.645802 -v 1.319164 1.111202 2.703792 -v 1.478891 1.018792 2.769953 -v 1.652204 0.961886 2.841742 -v 1.670232 2.923456 2.808013 -v 1.514254 2.866550 2.703792 -v 1.370504 2.774141 2.607742 -v 1.244506 2.649778 2.523552 -v 1.141103 2.498241 2.454460 -v 1.064266 2.325355 2.403120 -v 1.016951 2.137761 2.371505 -v 1.000975 1.942671 2.360830 -v 1.016951 1.747581 2.371505 -v 1.064266 1.559988 2.403120 -v 1.141103 1.387101 2.454460 -v 1.244506 1.235564 2.523552 -v 1.370504 1.111202 2.607742 -v 1.514254 1.018792 2.703792 -v 1.670232 0.961886 2.808013 -v 1.694494 2.923456 2.778450 -v 1.561846 2.866550 2.645802 -v 1.439597 2.774141 2.523552 -v 1.332444 2.649778 2.416400 -v 1.244506 2.498241 2.328462 -v 1.179163 2.325355 2.263119 -v 1.138924 2.137761 2.222880 -v 1.125338 1.942671 2.209293 -v 1.138924 1.747581 2.222880 -v 1.179163 1.559988 2.263119 -v 1.244506 1.387101 2.328462 -v 1.332444 1.235564 2.416400 -v 1.439597 1.111202 2.523552 -v 1.561846 1.018792 2.645802 -v 1.694494 0.961886 2.778450 -v 1.724057 2.923456 2.754188 -v 1.619836 2.866550 2.598210 -v 1.523786 2.774141 2.454460 -v 1.439596 2.649778 2.328462 -v 1.370504 2.498241 2.225058 -v 1.319164 2.325355 2.148222 -v 1.287549 2.137761 2.100907 -v 1.276875 1.942671 2.084931 -v 1.287549 1.747581 2.100907 -v 1.319164 1.559988 2.148222 -v 1.370504 1.387101 2.225058 -v 1.439596 1.235564 2.328462 -v 1.523786 1.111202 2.454460 -v 1.619836 1.018792 2.598210 -v 1.724057 0.961886 2.754188 -v 1.757786 2.923456 2.736160 -v 1.685997 2.866550 2.562846 -v 1.619837 2.774141 2.403120 -v 1.561846 2.649778 2.263118 -v 1.514255 2.498241 2.148222 -v 1.478891 2.325355 2.062847 -v 1.457114 2.137761 2.010273 -v 1.449761 1.942671 1.992521 -v 1.457114 1.747581 2.010273 -v 1.478891 1.559988 2.062847 -v 1.514255 1.387101 2.148222 -v 1.561846 1.235564 2.263118 -v 1.619837 1.111202 2.403120 -v 1.685997 1.018792 2.562846 -v 1.757786 0.961886 2.736160 -v 1.794384 2.923456 2.725058 -v 1.757786 2.866550 2.541070 -v 1.724058 2.774141 2.371505 -v 1.694494 2.649778 2.222880 -v 1.670232 2.498241 2.100907 -v 1.652204 2.325355 2.010273 -v 1.641102 2.137761 1.954461 -v 1.637354 1.942671 1.935616 -v 1.641102 1.747581 1.954461 -v 1.652204 1.559988 2.010273 -v 1.670232 1.387101 2.100907 -v 1.694494 1.235564 2.222880 -v 1.724058 1.111202 2.371505 -v 1.757786 1.018792 2.541070 -v 1.794384 0.961886 2.725058 -v 1.832444 2.923456 2.721310 -v 1.832444 2.866550 2.533716 -v 1.832444 2.649778 2.209293 -v 1.832444 2.325355 1.992521 -v 1.832444 1.559988 1.992521 -v 1.832444 1.235564 2.209293 -v 1.832444 1.111202 2.360830 -v 1.832444 1.018792 2.533716 -v 1.832444 0.961886 2.721310 -vn -0.0000 -0.7041 -0.7101 -vn 0.1092 -0.8286 -0.5490 -vn -0.0000 -0.8286 -0.5598 -vn -0.0000 0.3805 -0.9248 -vn 0.1626 0.5528 -0.8173 -vn 0.1804 0.3805 -0.9070 -vn 0.0757 -0.9217 -0.3804 -vn -0.0000 -0.9217 -0.3879 -vn -0.0000 0.1939 -0.9810 -vn 0.1914 0.1939 -0.9622 -vn 0.0392 -0.9796 -0.1971 -vn -0.0000 -0.9796 -0.2010 -vn 0.1951 -0.0000 -0.9808 -vn -0.0000 -0.0000 -1.0000 -vn -0.0000 0.9796 -0.2010 -vn -0.0000 1.0000 -0.0000 -vn 0.0392 0.9796 -0.1971 -vn -0.0000 -1.0000 -0.0000 -vn 0.1914 -0.1939 -0.9622 -vn -0.0000 -0.1939 -0.9810 -vn -0.0000 0.9217 -0.3879 -vn 0.0757 0.9217 -0.3804 -vn 0.1804 -0.3805 -0.9070 -vn -0.0000 -0.3805 -0.9248 -vn -0.0000 0.8286 -0.5598 -vn 0.1092 0.8286 -0.5490 -vn 0.1626 -0.5528 -0.8173 -vn -0.0000 -0.5528 -0.8333 -vn -0.0000 0.7041 -0.7101 -vn 0.1385 0.7041 -0.6965 -vn 0.1385 -0.7041 -0.6965 -vn -0.0000 0.5528 -0.8333 -vn 0.2718 -0.7041 -0.6561 -vn 0.3189 0.5528 -0.7699 -vn 0.2142 -0.8286 -0.5172 -vn 0.3539 0.3805 -0.8544 -vn 0.1484 -0.9217 -0.3584 -vn 0.3754 0.1939 -0.9063 -vn 0.0769 -0.9796 -0.1857 -vn 0.3827 -0.0000 -0.9239 -vn 0.0769 0.9796 -0.1857 -vn 0.3754 -0.1939 -0.9063 -vn 0.1484 0.9217 -0.3584 -vn 0.3539 -0.3805 -0.8544 -vn 0.2142 0.8286 -0.5172 -vn 0.3189 -0.5528 -0.7699 -vn 0.2718 0.7041 -0.6561 -vn 0.1117 0.9796 -0.1671 -vn 0.1117 -0.9796 -0.1671 -vn 0.5556 -0.0000 -0.8315 -vn 0.5450 -0.1939 -0.8157 -vn 0.2155 0.9217 -0.3225 -vn 0.5138 -0.3805 -0.7689 -vn 0.3110 0.8286 -0.4654 -vn 0.4630 -0.5528 -0.6929 -vn 0.3945 0.7041 -0.5905 -vn 0.3945 -0.7041 -0.5905 -vn 0.4630 0.5528 -0.6929 -vn 0.3110 -0.8286 -0.4654 -vn 0.5138 0.3805 -0.7689 -vn 0.2155 -0.9217 -0.3225 -vn 0.5450 0.1939 -0.8157 -vn 0.5893 0.5528 -0.5893 -vn 0.3958 -0.8286 -0.3958 -vn 0.6539 0.3805 -0.6539 -vn 0.2743 -0.9217 -0.2743 -vn 0.6937 0.1939 -0.6937 -vn 0.1421 -0.9796 -0.1421 -vn 0.7071 -0.0000 -0.7071 -vn 0.1421 0.9796 -0.1421 -vn 0.6937 -0.1939 -0.6937 -vn 0.2743 0.9217 -0.2743 -vn 0.6539 -0.3805 -0.6539 -vn 0.3958 0.8286 -0.3958 -vn 0.5893 -0.5528 -0.5893 -vn 0.5021 0.7041 -0.5021 -vn 0.5021 -0.7041 -0.5021 -vn 0.8157 -0.1939 -0.5450 -vn 0.3225 0.9217 -0.2155 -vn 0.7689 -0.3805 -0.5138 -vn 0.4654 0.8286 -0.3110 -vn 0.6929 -0.5528 -0.4630 -vn 0.5905 0.7041 -0.3945 -vn 0.5905 -0.7041 -0.3945 -vn 0.6929 0.5528 -0.4630 -vn 0.4654 -0.8286 -0.3110 -vn 0.7689 0.3805 -0.5138 -vn 0.3225 -0.9217 -0.2155 -vn 0.8157 0.1939 -0.5450 -vn 0.1671 -0.9796 -0.1117 -vn 0.8315 -0.0000 -0.5556 -vn 0.1671 0.9796 -0.1117 -vn 0.5172 -0.8286 -0.2142 -vn 0.8544 0.3805 -0.3539 -vn 0.3584 -0.9217 -0.1484 -vn 0.9063 0.1939 -0.3754 -vn 0.1857 -0.9796 -0.0769 -vn 0.9239 -0.0000 -0.3827 -vn 0.1857 0.9796 -0.0769 -vn 0.9063 -0.1939 -0.3754 -vn 0.3584 0.9217 -0.1484 -vn 0.8544 -0.3805 -0.3539 -vn 0.5172 0.8286 -0.2142 -vn 0.7699 -0.5528 -0.3189 -vn 0.6561 0.7041 -0.2718 -vn 0.6561 -0.7041 -0.2718 -vn 0.7699 0.5528 -0.3189 -vn 0.9070 -0.3805 -0.1804 -vn 0.5490 0.8286 -0.1092 -vn 0.8173 -0.5528 -0.1626 -vn 0.6965 0.7041 -0.1385 -vn 0.6965 -0.7041 -0.1385 -vn 0.8173 0.5528 -0.1626 -vn 0.5490 -0.8286 -0.1092 -vn 0.9070 0.3805 -0.1804 -vn 0.3804 -0.9217 -0.0757 -vn 0.9622 0.1939 -0.1914 -vn 0.1971 -0.9796 -0.0392 -vn 0.9808 -0.0000 -0.1951 -vn 0.1971 0.9796 -0.0392 -vn 0.9622 -0.1939 -0.1914 -vn 0.3804 0.9217 -0.0757 -vn 0.3879 -0.9217 -0.0000 -vn 0.9248 0.3805 -0.0000 -vn 0.9810 0.1939 -0.0000 -vn 0.2010 -0.9796 -0.0000 -vn 1.0000 -0.0000 -0.0000 -vn 0.2010 0.9796 -0.0000 -vn 0.9810 -0.1939 -0.0000 -vn 0.3879 0.9217 -0.0000 -vn 0.9248 -0.3805 -0.0000 -vn 0.5598 0.8286 -0.0000 -vn 0.8333 -0.5528 -0.0000 -vn 0.7101 0.7041 -0.0000 -vn 0.7101 -0.7041 -0.0000 -vn 0.8333 0.5528 -0.0000 -vn 0.5598 -0.8286 -0.0000 -vn 0.5490 0.8286 0.1092 -vn 0.9070 -0.3805 0.1804 -vn 0.8173 -0.5528 0.1626 -vn 0.6965 0.7041 0.1385 -vn 0.6965 -0.7041 0.1385 -vn 0.8173 0.5528 0.1626 -vn 0.5490 -0.8286 0.1092 -vn 0.9070 0.3805 0.1804 -vn 0.3804 -0.9217 0.0757 -vn 0.9622 0.1939 0.1914 -vn 0.1971 -0.9796 0.0392 -vn 0.9808 -0.0000 0.1951 -vn 0.1971 0.9796 0.0392 -vn 0.9622 -0.1939 0.1914 -vn 0.3804 0.9217 0.0757 -vn 0.8544 0.3805 0.3539 -vn 0.9063 0.1939 0.3754 -vn 0.3584 -0.9217 0.1484 -vn 0.1857 -0.9796 0.0769 -vn 0.9239 -0.0000 0.3827 -vn 0.1857 0.9796 0.0769 -vn 0.9063 -0.1939 0.3754 -vn 0.3584 0.9217 0.1484 -vn 0.8544 -0.3805 0.3539 -vn 0.5172 0.8286 0.2142 -vn 0.7699 -0.5528 0.3189 -vn 0.6561 0.7041 0.2718 -vn 0.6561 -0.7041 0.2718 -vn 0.7699 0.5528 0.3189 -vn 0.5172 -0.8286 0.2142 -vn 0.7689 -0.3805 0.5138 -vn 0.6929 -0.5528 0.4630 -vn 0.5905 0.7041 0.3945 -vn 0.5905 -0.7041 0.3945 -vn 0.6929 0.5528 0.4630 -vn 0.4654 -0.8286 0.3110 -vn 0.7689 0.3805 0.5138 -vn 0.3225 -0.9217 0.2155 -vn 0.8157 0.1939 0.5450 -vn 0.1671 -0.9796 0.1117 -vn 0.8315 -0.0000 0.5556 -vn 0.1671 0.9796 0.1117 -vn 0.8157 -0.1939 0.5450 -vn 0.3225 0.9217 0.2155 -vn 0.4654 0.8286 0.3110 -vn 0.2743 -0.9217 0.2743 -vn 0.1421 -0.9796 0.1421 -vn 0.6937 0.1939 0.6937 -vn 0.7071 -0.0000 0.7071 -vn 0.1421 0.9796 0.1421 -vn 0.6937 -0.1939 0.6937 -vn 0.2743 0.9217 0.2743 -vn 0.6539 -0.3805 0.6539 -vn 0.3958 0.8286 0.3958 -vn 0.5893 -0.5528 0.5893 -vn 0.5021 0.7041 0.5021 -vn 0.5021 -0.7041 0.5021 -vn 0.5893 0.5528 0.5893 -vn 0.3958 -0.8286 0.3958 -vn 0.6539 0.3805 0.6539 -vn 0.3945 0.7041 0.5905 -vn 0.3945 -0.7041 0.5905 -vn 0.4630 0.5528 0.6929 -vn 0.3110 -0.8286 0.4654 -vn 0.5138 0.3805 0.7689 -vn 0.2155 -0.9217 0.3225 -vn 0.5450 0.1939 0.8157 -vn 0.1117 -0.9796 0.1671 -vn 0.5556 -0.0000 0.8315 -vn 0.1117 0.9796 0.1671 -vn 0.5450 -0.1939 0.8157 -vn 0.2155 0.9217 0.3225 -vn 0.5138 -0.3805 0.7689 -vn 0.3110 0.8286 0.4654 -vn 0.4630 -0.5528 0.6929 -vn 0.3754 0.1939 0.9063 -vn 0.3827 -0.0000 0.9239 -vn 0.0769 0.9796 0.1857 -vn 0.0769 -0.9796 0.1857 -vn 0.3754 -0.1939 0.9063 -vn 0.1484 0.9217 0.3584 -vn 0.3539 -0.3805 0.8544 -vn 0.2142 0.8286 0.5172 -vn 0.3189 -0.5528 0.7699 -vn 0.2718 0.7041 0.6561 -vn 0.2718 -0.7041 0.6561 -vn 0.3189 0.5528 0.7699 -vn 0.2142 -0.8286 0.5172 -vn 0.3539 0.3805 0.8544 -vn 0.1484 -0.9217 0.3584 -vn 0.1385 -0.7041 0.6965 -vn 0.1385 0.7041 0.6965 -vn 0.1626 0.5528 0.8173 -vn 0.1092 -0.8286 0.5490 -vn 0.1804 0.3805 0.9070 -vn 0.0757 -0.9217 0.3804 -vn 0.1914 0.1939 0.9622 -vn 0.0392 -0.9796 0.1971 -vn 0.1951 -0.0000 0.9808 -vn 0.0392 0.9796 0.1971 -vn 0.1914 -0.1939 0.9622 -vn 0.0757 0.9217 0.3804 -vn 0.1804 -0.3805 0.9070 -vn 0.1092 0.8286 0.5490 -vn 0.1626 -0.5528 0.8173 -vn -0.0000 -0.9796 0.2010 -vn -0.0000 -0.1939 0.9810 -vn -0.0000 0.9217 0.3879 -vn -0.0000 -0.3805 0.9248 -vn -0.0000 0.8286 0.5598 -vn -0.0000 -0.5528 0.8333 -vn -0.0000 0.7041 0.7101 -vn -0.0000 -0.7041 0.7101 -vn -0.0000 0.5528 0.8333 -vn -0.0000 -0.8286 0.5598 -vn -0.0000 0.3805 0.9248 -vn -0.0000 -0.9217 0.3879 -vn -0.0000 0.1939 0.9810 -vn -0.0000 -0.0000 1.0000 -vn -0.0000 0.9796 0.2010 -vn -0.1385 -0.7041 0.6965 -vn -0.1092 -0.8286 0.5490 -vn -0.1804 0.3805 0.9070 -vn -0.0757 -0.9217 0.3804 -vn -0.1914 0.1939 0.9622 -vn -0.0392 -0.9796 0.1971 -vn -0.1951 -0.0000 0.9808 -vn -0.0392 0.9796 0.1971 -vn -0.1914 -0.1939 0.9622 -vn -0.0757 0.9217 0.3804 -vn -0.1804 -0.3805 0.9070 -vn -0.1092 0.8286 0.5490 -vn -0.1626 -0.5528 0.8173 -vn -0.1385 0.7041 0.6965 -vn -0.1626 0.5528 0.8173 -vn -0.0769 0.9796 0.1857 -vn -0.1484 0.9217 0.3584 -vn -0.3539 -0.3805 0.8544 -vn -0.2142 0.8286 0.5172 -vn -0.3189 -0.5528 0.7699 -vn -0.2718 0.7041 0.6561 -vn -0.2718 -0.7041 0.6561 -vn -0.3189 0.5528 0.7699 -vn -0.2142 -0.8286 0.5172 -vn -0.3539 0.3805 0.8544 -vn -0.1484 -0.9217 0.3584 -vn -0.3754 0.1939 0.9063 -vn -0.0769 -0.9796 0.1857 -vn -0.3827 -0.0000 0.9239 -vn -0.3754 -0.1939 0.9063 -vn -0.5138 0.3805 0.7689 -vn -0.2155 -0.9217 0.3225 -vn -0.5450 0.1939 0.8157 -vn -0.1117 -0.9796 0.1671 -vn -0.5556 -0.0000 0.8315 -vn -0.1117 0.9796 0.1671 -vn -0.5450 -0.1939 0.8157 -vn -0.2155 0.9217 0.3225 -vn -0.5138 -0.3805 0.7689 -vn -0.3110 0.8286 0.4654 -vn -0.4630 -0.5528 0.6929 -vn -0.3945 0.7041 0.5905 -vn -0.3945 -0.7041 0.5905 -vn -0.4630 0.5528 0.6929 -vn -0.3110 -0.8286 0.4654 -vn -0.6539 -0.3805 0.6539 -vn -0.3958 0.8286 0.3958 -vn -0.5893 -0.5528 0.5893 -vn -0.5021 0.7041 0.5021 -vn -0.5021 -0.7041 0.5021 -vn -0.5893 0.5528 0.5893 -vn -0.3958 -0.8286 0.3958 -vn -0.6539 0.3805 0.6539 -vn -0.2743 -0.9217 0.2743 -vn -0.6937 0.1939 0.6937 -vn -0.1421 -0.9796 0.1421 -vn -0.7071 -0.0000 0.7071 -vn -0.1421 0.9796 0.1421 -vn -0.6937 -0.1939 0.6937 -vn -0.2743 0.9217 0.2743 -vn -0.3225 -0.9217 0.2155 -vn -0.7689 0.3805 0.5138 -vn -0.8157 0.1939 0.5450 -vn -0.1671 -0.9796 0.1117 -vn -0.8315 -0.0000 0.5556 -vn -0.1671 0.9796 0.1117 -vn -0.8157 -0.1939 0.5450 -vn -0.3225 0.9217 0.2155 -vn -0.7689 -0.3805 0.5138 -vn -0.4654 0.8286 0.3110 -vn -0.6929 -0.5528 0.4630 -vn -0.5905 0.7041 0.3945 -vn -0.5905 -0.7041 0.3945 -vn -0.6929 0.5528 0.4630 -vn -0.4654 -0.8286 0.3110 -vn -0.5172 0.8286 0.2142 -vn -0.8544 -0.3805 0.3539 -vn -0.7699 -0.5528 0.3189 -vn -0.6561 0.7041 0.2718 -vn -0.6561 -0.7041 0.2718 -vn -0.7699 0.5528 0.3189 -vn -0.5172 -0.8286 0.2142 -vn -0.8544 0.3805 0.3539 -vn -0.3584 -0.9217 0.1484 -vn -0.9063 0.1939 0.3754 -vn -0.1857 -0.9796 0.0769 -vn -0.9239 -0.0000 0.3827 -vn -0.1857 0.9796 0.0769 -vn -0.9063 -0.1939 0.3754 -vn -0.3584 0.9217 0.1484 -vn -0.9070 0.3805 0.1804 -vn -0.9622 0.1939 0.1914 -vn -0.1971 -0.9796 0.0392 -vn -0.9808 -0.0000 0.1951 -vn -0.1971 0.9796 0.0392 -vn -0.9622 -0.1939 0.1914 -vn -0.3804 0.9217 0.0757 -vn -0.9070 -0.3805 0.1804 -vn -0.5490 0.8286 0.1092 -vn -0.8173 -0.5528 0.1626 -vn -0.6965 0.7041 0.1385 -vn -0.6965 -0.7041 0.1385 -vn -0.8173 0.5528 0.1626 -vn -0.5490 -0.8286 0.1092 -vn -0.3804 -0.9217 0.0757 -vn -0.9248 -0.3805 -0.0000 -vn -0.8333 -0.5528 -0.0000 -vn -0.7101 0.7041 -0.0000 -vn -0.7101 -0.7041 -0.0000 -vn -0.8333 0.5528 -0.0000 -vn -0.5598 -0.8286 -0.0000 -vn -0.9248 0.3805 -0.0000 -vn -0.3879 -0.9217 -0.0000 -vn -0.9810 0.1939 -0.0000 -vn -0.2010 -0.9796 -0.0000 -vn -1.0000 -0.0000 -0.0000 -vn -0.2010 0.9796 -0.0000 -vn -0.9810 -0.1939 -0.0000 -vn -0.3879 0.9217 -0.0000 -vn -0.5598 0.8286 -0.0000 -vn -0.1971 -0.9796 -0.0392 -vn -0.9622 0.1939 -0.1914 -vn -0.9808 -0.0000 -0.1951 -vn -0.1971 0.9796 -0.0392 -vn -0.9622 -0.1939 -0.1914 -vn -0.3804 0.9217 -0.0757 -vn -0.9070 -0.3805 -0.1804 -vn -0.5490 0.8286 -0.1092 -vn -0.8173 -0.5528 -0.1626 -vn -0.6965 0.7041 -0.1385 -vn -0.6965 -0.7041 -0.1385 -vn -0.8173 0.5528 -0.1626 -vn -0.5490 -0.8286 -0.1092 -vn -0.9070 0.3805 -0.1804 -vn -0.3804 -0.9217 -0.0757 -vn -0.6561 -0.7041 -0.2718 -vn -0.6561 0.7041 -0.2718 -vn -0.7699 0.5528 -0.3189 -vn -0.5172 -0.8286 -0.2142 -vn -0.8544 0.3805 -0.3539 -vn -0.3584 -0.9217 -0.1484 -vn -0.9063 0.1939 -0.3754 -vn -0.1857 -0.9796 -0.0769 -vn -0.9239 -0.0000 -0.3827 -vn -0.1857 0.9796 -0.0769 -vn -0.9063 -0.1939 -0.3754 -vn -0.3584 0.9217 -0.1484 -vn -0.8544 -0.3805 -0.3539 -vn -0.5172 0.8286 -0.2142 -vn -0.7699 -0.5528 -0.3189 -vn -0.1671 0.9796 -0.1117 -vn -0.1671 -0.9796 -0.1117 -vn -0.8157 -0.1939 -0.5450 -vn -0.3225 0.9217 -0.2155 -vn -0.7689 -0.3805 -0.5138 -vn -0.4654 0.8286 -0.3110 -vn -0.6929 -0.5528 -0.4630 -vn -0.5905 0.7041 -0.3945 -vn -0.5905 -0.7041 -0.3945 -vn -0.6929 0.5528 -0.4630 -vn -0.4654 -0.8286 -0.3110 -vn -0.7689 0.3805 -0.5138 -vn -0.3225 -0.9217 -0.2155 -vn -0.8157 0.1939 -0.5450 -vn -0.8315 -0.0000 -0.5556 -vn -0.5021 0.7041 -0.5021 -vn -0.5893 0.5528 -0.5893 -vn -0.5021 -0.7041 -0.5021 -vn -0.3958 -0.8286 -0.3958 -vn -0.6539 0.3805 -0.6539 -vn -0.2743 -0.9217 -0.2743 -vn -0.6937 0.1939 -0.6937 -vn -0.1421 -0.9796 -0.1421 -vn -0.7071 -0.0000 -0.7071 -vn -0.1421 0.9796 -0.1421 -vn -0.6937 -0.1939 -0.6937 -vn -0.2743 0.9217 -0.2743 -vn -0.6539 -0.3805 -0.6539 -vn -0.3958 0.8286 -0.3958 -vn -0.5893 -0.5528 -0.5893 -vn -0.5450 -0.1939 -0.8157 -vn -0.2155 0.9217 -0.3225 -vn -0.5138 -0.3805 -0.7689 -vn -0.3110 0.8286 -0.4654 -vn -0.4630 -0.5528 -0.6929 -vn -0.3945 0.7041 -0.5905 -vn -0.3945 -0.7041 -0.5905 -vn -0.4630 0.5528 -0.6929 -vn -0.3110 -0.8286 -0.4654 -vn -0.5138 0.3805 -0.7689 -vn -0.2155 -0.9217 -0.3225 -vn -0.5450 0.1939 -0.8157 -vn -0.1117 -0.9796 -0.1671 -vn -0.5556 -0.0000 -0.8315 -vn -0.1117 0.9796 -0.1671 -vn -0.2718 -0.7041 -0.6561 -vn -0.2142 -0.8286 -0.5172 -vn -0.3539 0.3805 -0.8544 -vn -0.1484 -0.9217 -0.3584 -vn -0.3754 0.1939 -0.9063 -vn -0.0769 -0.9796 -0.1857 -vn -0.3827 -0.0000 -0.9239 -vn -0.0769 0.9796 -0.1857 -vn -0.3754 -0.1939 -0.9063 -vn -0.1484 0.9217 -0.3584 -vn -0.3539 -0.3805 -0.8544 -vn -0.2142 0.8286 -0.5172 -vn -0.3189 -0.5528 -0.7699 -vn -0.2718 0.7041 -0.6561 -vn -0.3189 0.5528 -0.7699 -vn -0.0757 0.9217 -0.3804 -vn -0.1804 -0.3805 -0.9070 -vn -0.1092 0.8286 -0.5490 -vn -0.1626 -0.5528 -0.8173 -vn -0.1385 0.7041 -0.6965 -vn -0.1385 -0.7041 -0.6965 -vn -0.1626 0.5528 -0.8173 -vn -0.1092 -0.8286 -0.5490 -vn -0.1804 0.3805 -0.9070 -vn -0.0757 -0.9217 -0.3804 -vn -0.1914 0.1939 -0.9622 -vn -0.0392 -0.9796 -0.1971 -vn -0.1951 -0.0000 -0.9808 -vn -0.0392 0.9796 -0.1971 -vn -0.1914 -0.1939 -0.9622 -vt 0.750000 0.812500 -vt 0.750000 0.687500 -vt 0.750000 0.562500 -vt 0.750000 0.500000 -vt 0.750000 0.437500 -vt 0.750000 0.312500 -vt 0.718750 0.937500 -vt 0.718750 0.875000 -vt 0.718750 0.812500 -vt 0.718750 0.750000 -vt 0.718750 0.687500 -vt 0.718750 0.625000 -vt 0.718750 0.562500 -vt 0.718750 0.500000 -vt 0.718750 0.437500 -vt 0.718750 0.375000 -vt 0.718750 0.312500 -vt 0.718750 0.250000 -vt 0.718750 0.187500 -vt 0.718750 0.125000 -vt 0.718750 0.062500 -vt 0.687500 0.937500 -vt 0.687500 0.875000 -vt 0.687500 0.812500 -vt 0.687500 0.750000 -vt 0.687500 0.687500 -vt 0.687500 0.625000 -vt 0.687500 0.562500 -vt 0.687500 0.500000 -vt 0.687500 0.437500 -vt 0.687500 0.375000 -vt 0.687500 0.312500 -vt 0.687500 0.250000 -vt 0.687500 0.187500 -vt 0.687500 0.125000 -vt 0.687500 0.062500 -vt 0.656250 0.937500 -vt 0.656250 0.875000 -vt 0.656250 0.812500 -vt 0.656250 0.750000 -vt 0.656250 0.687500 -vt 0.656250 0.625000 -vt 0.656250 0.562500 -vt 0.656250 0.500000 -vt 0.656250 0.437500 -vt 0.656250 0.375000 -vt 0.656250 0.312500 -vt 0.656250 0.250000 -vt 0.656250 0.187500 -vt 0.656250 0.125000 -vt 0.656250 0.062500 -vt 0.625000 0.937500 -vt 0.625000 0.875000 -vt 0.625000 0.812500 -vt 0.625000 0.750000 -vt 0.625000 0.687500 -vt 0.625000 0.625000 -vt 0.625000 0.562500 -vt 0.625000 0.500000 -vt 0.625000 0.437500 -vt 0.625000 0.375000 -vt 0.625000 0.312500 -vt 0.625000 0.250000 -vt 0.625000 0.187500 -vt 0.625000 0.125000 -vt 0.625000 0.062500 -vt 0.593750 0.937500 -vt 0.593750 0.875000 -vt 0.593750 0.812500 -vt 0.593750 0.750000 -vt 0.593750 0.687500 -vt 0.593750 0.625000 -vt 0.593750 0.562500 -vt 0.593750 0.500000 -vt 0.593750 0.437500 -vt 0.593750 0.375000 -vt 0.593750 0.312500 -vt 0.593750 0.250000 -vt 0.593750 0.187500 -vt 0.593750 0.125000 -vt 0.593750 0.062500 -vt 0.734375 1.000000 -vt 0.703125 1.000000 -vt 0.671875 1.000000 -vt 0.640625 1.000000 -vt 0.609375 1.000000 -vt 0.578125 1.000000 -vt 0.546875 1.000000 -vt 0.515625 1.000000 -vt 0.484375 1.000000 -vt 0.453125 1.000000 -vt 0.421875 1.000000 -vt 0.390625 1.000000 -vt 0.359375 1.000000 -vt 0.328125 1.000000 -vt 0.296875 1.000000 -vt 0.265625 1.000000 -vt 0.234375 1.000000 -vt 0.203125 1.000000 -vt 0.171875 1.000000 -vt 0.140625 1.000000 -vt 0.109375 1.000000 -vt 0.078125 1.000000 -vt 0.046875 1.000000 -vt 0.015625 1.000000 -vt 0.984375 1.000000 -vt 0.953125 1.000000 -vt 0.921875 1.000000 -vt 0.890625 1.000000 -vt 0.859375 1.000000 -vt 0.828125 1.000000 -vt 0.796875 1.000000 -vt 0.765625 1.000000 -vt 0.562500 0.937500 -vt 0.562500 0.875000 -vt 0.562500 0.812500 -vt 0.562500 0.750000 -vt 0.562500 0.687500 -vt 0.562500 0.625000 -vt 0.562500 0.562500 -vt 0.562500 0.500000 -vt 0.562500 0.437500 -vt 0.562500 0.375000 -vt 0.562500 0.312500 -vt 0.562500 0.250000 -vt 0.562500 0.187500 -vt 0.562500 0.125000 -vt 0.562500 0.062500 -vt 0.531250 0.937500 -vt 0.531250 0.875000 -vt 0.531250 0.812500 -vt 0.531250 0.750000 -vt 0.531250 0.687500 -vt 0.531250 0.625000 -vt 0.531250 0.562500 -vt 0.531250 0.500000 -vt 0.531250 0.437500 -vt 0.531250 0.375000 -vt 0.531250 0.312500 -vt 0.531250 0.250000 -vt 0.531250 0.187500 -vt 0.531250 0.125000 -vt 0.531250 0.062500 -vt 0.500000 0.937500 -vt 0.500000 0.875000 -vt 0.500000 0.812500 -vt 0.500000 0.750000 -vt 0.500000 0.687500 -vt 0.500000 0.625000 -vt 0.500000 0.562500 -vt 0.500000 0.500000 -vt 0.500000 0.437500 -vt 0.500000 0.375000 -vt 0.500000 0.312500 -vt 0.500000 0.250000 -vt 0.500000 0.187500 -vt 0.500000 0.125000 -vt 0.500000 0.062500 -vt 0.468750 0.937500 -vt 0.468750 0.875000 -vt 0.468750 0.812500 -vt 0.468750 0.750000 -vt 0.468750 0.687500 -vt 0.468750 0.625000 -vt 0.468750 0.562500 -vt 0.468750 0.500000 -vt 0.468750 0.437500 -vt 0.468750 0.375000 -vt 0.468750 0.312500 -vt 0.468750 0.250000 -vt 0.468750 0.187500 -vt 0.468750 0.125000 -vt 0.468750 0.062500 -vt 0.437500 0.937500 -vt 0.437500 0.875000 -vt 0.437500 0.812500 -vt 0.437500 0.750000 -vt 0.437500 0.687500 -vt 0.437500 0.625000 -vt 0.437500 0.562500 -vt 0.437500 0.500000 -vt 0.437500 0.437500 -vt 0.437500 0.375000 -vt 0.437500 0.312500 -vt 0.437500 0.250000 -vt 0.437500 0.187500 -vt 0.437500 0.125000 -vt 0.437500 0.062500 -vt 0.406250 0.937500 -vt 0.406250 0.875000 -vt 0.406250 0.812500 -vt 0.406250 0.750000 -vt 0.406250 0.687500 -vt 0.406250 0.625000 -vt 0.406250 0.562500 -vt 0.406250 0.500000 -vt 0.406250 0.437500 -vt 0.406250 0.375000 -vt 0.406250 0.312500 -vt 0.406250 0.250000 -vt 0.406250 0.187500 -vt 0.406250 0.125000 -vt 0.406250 0.062500 -vt 0.375000 0.937500 -vt 0.375000 0.875000 -vt 0.375000 0.812500 -vt 0.375000 0.750000 -vt 0.375000 0.687500 -vt 0.375000 0.625000 -vt 0.375000 0.562500 -vt 0.375000 0.500000 -vt 0.375000 0.437500 -vt 0.375000 0.375000 -vt 0.375000 0.312500 -vt 0.375000 0.250000 -vt 0.375000 0.187500 -vt 0.375000 0.125000 -vt 0.375000 0.062500 -vt 0.343750 0.937500 -vt 0.343750 0.875000 -vt 0.343750 0.812500 -vt 0.343750 0.750000 -vt 0.343750 0.687500 -vt 0.343750 0.625000 -vt 0.343750 0.562500 -vt 0.343750 0.500000 -vt 0.343750 0.437500 -vt 0.343750 0.375000 -vt 0.343750 0.312500 -vt 0.343750 0.250000 -vt 0.343750 0.187500 -vt 0.343750 0.125000 -vt 0.343750 0.062500 -vt 0.312500 0.937500 -vt 0.312500 0.875000 -vt 0.312500 0.812500 -vt 0.312500 0.750000 -vt 0.312500 0.687500 -vt 0.312500 0.625000 -vt 0.312500 0.562500 -vt 0.312500 0.500000 -vt 0.312500 0.437500 -vt 0.312500 0.375000 -vt 0.312500 0.312500 -vt 0.312500 0.250000 -vt 0.312500 0.187500 -vt 0.312500 0.125000 -vt 0.312500 0.062500 -vt 0.281250 0.937500 -vt 0.281250 0.875000 -vt 0.281250 0.812500 -vt 0.281250 0.750000 -vt 0.281250 0.687500 -vt 0.281250 0.625000 -vt 0.281250 0.562500 -vt 0.281250 0.500000 -vt 0.281250 0.437500 -vt 0.281250 0.375000 -vt 0.281250 0.312500 -vt 0.281250 0.250000 -vt 0.281250 0.187500 -vt 0.281250 0.125000 -vt 0.281250 0.062500 -vt 0.250000 0.937500 -vt 0.250000 0.875000 -vt 0.250000 0.812500 -vt 0.250000 0.750000 -vt 0.250000 0.687500 -vt 0.250000 0.625000 -vt 0.250000 0.562500 -vt 0.250000 0.500000 -vt 0.250000 0.437500 -vt 0.250000 0.375000 -vt 0.250000 0.312500 -vt 0.250000 0.250000 -vt 0.250000 0.187500 -vt 0.250000 0.125000 -vt 0.250000 0.062500 -vt 0.218750 0.937500 -vt 0.218750 0.875000 -vt 0.218750 0.812500 -vt 0.218750 0.750000 -vt 0.218750 0.687500 -vt 0.218750 0.625000 -vt 0.218750 0.562500 -vt 0.218750 0.500000 -vt 0.218750 0.437500 -vt 0.218750 0.375000 -vt 0.218750 0.312500 -vt 0.218750 0.250000 -vt 0.218750 0.187500 -vt 0.218750 0.125000 -vt 0.218750 0.062500 -vt 0.187500 0.937500 -vt 0.187500 0.875000 -vt 0.187500 0.812500 -vt 0.187500 0.750000 -vt 0.187500 0.687500 -vt 0.187500 0.625000 -vt 0.187500 0.562500 -vt 0.187500 0.500000 -vt 0.187500 0.437500 -vt 0.187500 0.375000 -vt 0.187500 0.312500 -vt 0.187500 0.250000 -vt 0.187500 0.187500 -vt 0.187500 0.125000 -vt 0.187500 0.062500 -vt 0.156250 0.937500 -vt 0.156250 0.875000 -vt 0.156250 0.812500 -vt 0.156250 0.750000 -vt 0.156250 0.687500 -vt 0.156250 0.625000 -vt 0.156250 0.562500 -vt 0.156250 0.500000 -vt 0.156250 0.437500 -vt 0.156250 0.375000 -vt 0.156250 0.312500 -vt 0.156250 0.250000 -vt 0.156250 0.187500 -vt 0.156250 0.125000 -vt 0.156250 0.062500 -vt 0.125000 0.937500 -vt 0.125000 0.875000 -vt 0.125000 0.812500 -vt 0.125000 0.750000 -vt 0.125000 0.687500 -vt 0.125000 0.625000 -vt 0.125000 0.562500 -vt 0.125000 0.500000 -vt 0.125000 0.437500 -vt 0.125000 0.375000 -vt 0.125000 0.312500 -vt 0.125000 0.250000 -vt 0.125000 0.187500 -vt 0.125000 0.125000 -vt 0.125000 0.062500 -vt 0.734375 0.000000 -vt 0.703125 0.000000 -vt 0.671875 0.000000 -vt 0.640625 0.000000 -vt 0.609375 0.000000 -vt 0.578125 0.000000 -vt 0.546875 0.000000 -vt 0.515625 0.000000 -vt 0.484375 0.000000 -vt 0.453125 0.000000 -vt 0.421875 0.000000 -vt 0.390625 0.000000 -vt 0.359375 0.000000 -vt 0.328125 0.000000 -vt 0.296875 0.000000 -vt 0.265625 0.000000 -vt 0.234375 0.000000 -vt 0.203125 0.000000 -vt 0.171875 0.000000 -vt 0.140625 0.000000 -vt 0.109375 0.000000 -vt 0.078125 0.000000 -vt 0.046875 0.000000 -vt 0.015625 0.000000 -vt 0.984375 0.000000 -vt 0.953125 0.000000 -vt 0.921875 0.000000 -vt 0.890625 0.000000 -vt 0.859375 0.000000 -vt 0.828125 0.000000 -vt 0.796875 0.000000 -vt 0.765625 0.000000 -vt 0.093750 0.937500 -vt 0.093750 0.875000 -vt 0.093750 0.812500 -vt 0.093750 0.750000 -vt 0.093750 0.687500 -vt 0.093750 0.625000 -vt 0.093750 0.562500 -vt 0.093750 0.500000 -vt 0.093750 0.437500 -vt 0.093750 0.375000 -vt 0.093750 0.312500 -vt 0.093750 0.250000 -vt 0.093750 0.187500 -vt 0.093750 0.125000 -vt 0.093750 0.062500 -vt 0.062500 0.937500 -vt 0.062500 0.875000 -vt 0.062500 0.812500 -vt 0.062500 0.750000 -vt 0.062500 0.687500 -vt 0.062500 0.625000 -vt 0.062500 0.562500 -vt 0.062500 0.500000 -vt 0.062500 0.437500 -vt 0.062500 0.375000 -vt 0.062500 0.312500 -vt 0.062500 0.250000 -vt 0.062500 0.187500 -vt 0.062500 0.125000 -vt 0.062500 0.062500 -vt 0.031250 0.937500 -vt 0.031250 0.875000 -vt 0.031250 0.812500 -vt 0.031250 0.750000 -vt 0.031250 0.687500 -vt 0.031250 0.625000 -vt 0.031250 0.562500 -vt 0.031250 0.500000 -vt 0.031250 0.437500 -vt 0.031250 0.375000 -vt 0.031250 0.312500 -vt 0.031250 0.250000 -vt 0.031250 0.187500 -vt 0.031250 0.125000 -vt 0.031250 0.062500 -vt 0.000000 0.937500 -vt 1.000000 0.937500 -vt 0.000000 0.875000 -vt 1.000000 0.875000 -vt 0.000000 0.812500 -vt 1.000000 0.812500 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 0.000000 0.687500 -vt 1.000000 0.687500 -vt 0.000000 0.625000 -vt 1.000000 0.625000 -vt 0.000000 0.562500 -vt 1.000000 0.562500 -vt 0.000000 0.500000 -vt 1.000000 0.500000 -vt 0.000000 0.437500 -vt 1.000000 0.437500 -vt 0.000000 0.375000 -vt 1.000000 0.375000 -vt 0.000000 0.312500 -vt 1.000000 0.312500 -vt 0.000000 0.250000 -vt 1.000000 0.250000 -vt 0.000000 0.187500 -vt 1.000000 0.187500 -vt 0.000000 0.125000 -vt 1.000000 0.125000 -vt 1.000000 0.062500 -vt 0.000000 0.062500 -vt 0.968750 0.937500 -vt 0.968750 0.875000 -vt 0.968750 0.812500 -vt 0.968750 0.750000 -vt 0.968750 0.687500 -vt 0.968750 0.625000 -vt 0.968750 0.562500 -vt 0.968750 0.500000 -vt 0.968750 0.437500 -vt 0.968750 0.375000 -vt 0.968750 0.312500 -vt 0.968750 0.250000 -vt 0.968750 0.187500 -vt 0.968750 0.125000 -vt 0.968750 0.062500 -vt 0.937500 0.937500 -vt 0.937500 0.875000 -vt 0.937500 0.812500 -vt 0.937500 0.750000 -vt 0.937500 0.687500 -vt 0.937500 0.625000 -vt 0.937500 0.562500 -vt 0.937500 0.500000 -vt 0.937500 0.437500 -vt 0.937500 0.375000 -vt 0.937500 0.312500 -vt 0.937500 0.250000 -vt 0.937500 0.187500 -vt 0.937500 0.125000 -vt 0.937500 0.062500 -vt 0.906250 0.937500 -vt 0.906250 0.875000 -vt 0.906250 0.812500 -vt 0.906250 0.750000 -vt 0.906250 0.687500 -vt 0.906250 0.625000 -vt 0.906250 0.562500 -vt 0.906250 0.500000 -vt 0.906250 0.437500 -vt 0.906250 0.375000 -vt 0.906250 0.312500 -vt 0.906250 0.250000 -vt 0.906250 0.187500 -vt 0.906250 0.125000 -vt 0.906250 0.062500 -vt 0.875000 0.937500 -vt 0.875000 0.875000 -vt 0.875000 0.812500 -vt 0.875000 0.750000 -vt 0.875000 0.687500 -vt 0.875000 0.625000 -vt 0.875000 0.562500 -vt 0.875000 0.500000 -vt 0.875000 0.437500 -vt 0.875000 0.375000 -vt 0.875000 0.312500 -vt 0.875000 0.250000 -vt 0.875000 0.187500 -vt 0.875000 0.125000 -vt 0.875000 0.062500 -vt 0.843750 0.937500 -vt 0.843750 0.875000 -vt 0.843750 0.812500 -vt 0.843750 0.750000 -vt 0.843750 0.687500 -vt 0.843750 0.625000 -vt 0.843750 0.562500 -vt 0.843750 0.500000 -vt 0.843750 0.437500 -vt 0.843750 0.375000 -vt 0.843750 0.312500 -vt 0.843750 0.250000 -vt 0.843750 0.187500 -vt 0.843750 0.125000 -vt 0.843750 0.062500 -vt 0.812500 0.937500 -vt 0.812500 0.875000 -vt 0.812500 0.812500 -vt 0.812500 0.750000 -vt 0.812500 0.687500 -vt 0.812500 0.625000 -vt 0.812500 0.562500 -vt 0.812500 0.500000 -vt 0.812500 0.437500 -vt 0.812500 0.375000 -vt 0.812500 0.312500 -vt 0.812500 0.250000 -vt 0.812500 0.187500 -vt 0.812500 0.125000 -vt 0.812500 0.062500 -vt 0.781250 0.937500 -vt 0.781250 0.875000 -vt 0.781250 0.812500 -vt 0.781250 0.750000 -vt 0.781250 0.687500 -vt 0.781250 0.625000 -vt 0.781250 0.562500 -vt 0.781250 0.500000 -vt 0.781250 0.437500 -vt 0.781250 0.375000 -vt 0.781250 0.312500 -vt 0.781250 0.250000 -vt 0.781250 0.187500 -vt 0.781250 0.125000 -vt 0.781250 0.062500 -vt 0.750000 0.937500 -vt 0.750000 0.875000 -vt 0.750000 0.750000 -vt 0.750000 0.625000 -vt 0.750000 0.375000 -vt 0.750000 0.250000 -vt 0.750000 0.187500 -vt 0.750000 0.125000 -vt 0.750000 0.062500 -f 479/556/1 19/19/2 480/557/3 -f 477/554/4 11/11/5 12/12/6 -f 480/557/3 20/20/7 481/558/8 -f 3/3/9 12/12/6 13/13/10 -f 481/558/8 21/21/11 482/559/12 -f 3/3/9 14/14/13 4/4/14 -f 474/551/15 82/82/16 7/7/17 -f 308/339/18 482/559/12 21/21/11 -f 4/4/14 15/15/19 5/5/20 -f 475/552/21 7/7/17 8/8/22 -f 5/5/20 16/16/23 478/555/24 -f 1/1/25 8/8/22 9/9/26 -f 478/555/24 17/17/27 6/6/28 -f 476/553/29 9/9/26 10/10/30 -f 6/6/28 18/18/31 479/556/1 -f 2/2/32 10/10/30 11/11/5 -f 17/17/27 33/33/33 18/18/31 -f 10/10/30 26/26/34 11/11/5 -f 19/19/2 33/33/33 34/34/35 -f 11/11/5 27/27/36 12/12/6 -f 20/20/7 34/34/35 35/35/37 -f 13/13/10 27/27/36 28/28/38 -f 20/20/7 36/36/39 21/21/11 -f 13/13/10 29/29/40 14/14/13 -f 7/7/17 82/83/16 22/22/41 -f 308/340/18 21/21/11 36/36/39 -f 14/14/13 30/30/42 15/15/19 -f 7/7/17 23/23/43 8/8/22 -f 15/15/19 31/31/44 16/16/23 -f 8/8/22 24/24/45 9/9/26 -f 16/16/23 32/32/46 17/17/27 -f 9/9/26 25/25/47 10/10/30 -f 22/22/41 82/84/16 37/37/48 -f 308/341/18 36/36/39 51/51/49 -f 30/30/42 44/44/50 45/45/51 -f 22/22/41 38/38/52 23/23/43 -f 30/30/42 46/46/53 31/31/44 -f 23/23/43 39/39/54 24/24/45 -f 32/32/46 46/46/53 47/47/55 -f 24/24/45 40/40/56 25/25/47 -f 33/33/33 47/47/55 48/48/57 -f 25/25/47 41/41/58 26/26/34 -f 34/34/35 48/48/57 49/49/59 -f 26/26/34 42/42/60 27/27/36 -f 34/34/35 50/50/61 35/35/37 -f 27/27/36 43/43/62 28/28/38 -f 35/35/37 51/51/49 36/36/39 -f 28/28/38 44/44/50 29/29/40 -f 40/40/56 56/56/63 41/41/58 -f 48/48/57 64/64/64 49/49/59 -f 41/41/58 57/57/65 42/42/60 -f 49/49/59 65/65/66 50/50/61 -f 43/43/62 57/57/65 58/58/67 -f 50/50/61 66/66/68 51/51/49 -f 44/44/50 58/58/67 59/59/69 -f 37/37/48 82/85/16 52/52/70 -f 308/342/18 51/51/49 66/66/68 -f 44/44/50 60/60/71 45/45/51 -f 37/37/48 53/53/72 38/38/52 -f 45/45/51 61/61/73 46/46/53 -f 38/38/52 54/54/74 39/39/54 -f 47/47/55 61/61/73 62/62/75 -f 39/39/54 55/55/76 40/40/56 -f 47/47/55 63/63/77 48/48/57 -f 59/59/69 75/75/78 60/60/71 -f 52/52/70 68/68/79 53/53/72 -f 60/60/71 76/76/80 61/61/73 -f 53/53/72 69/69/81 54/54/74 -f 62/62/75 76/76/80 77/77/82 -f 54/54/74 70/70/83 55/55/76 -f 62/62/75 78/78/84 63/63/77 -f 56/56/63 70/70/83 71/71/85 -f 63/63/77 79/79/86 64/64/64 -f 56/56/63 72/72/87 57/57/65 -f 65/65/66 79/79/86 80/80/88 -f 58/58/67 72/72/87 73/73/89 -f 65/65/66 81/81/90 66/66/68 -f 59/59/69 73/73/89 74/74/91 -f 52/52/70 82/86/16 67/67/92 -f 308/343/18 66/66/68 81/81/90 -f 78/78/84 95/126/93 79/79/86 -f 71/71/85 88/119/94 72/72/87 -f 79/79/86 96/127/95 80/80/88 -f 73/73/89 88/119/94 89/120/96 -f 81/81/90 96/127/95 97/128/97 -f 74/74/91 89/120/96 90/121/98 -f 67/67/92 82/87/16 83/114/99 -f 308/344/18 81/81/90 97/128/97 -f 74/74/91 91/122/100 75/75/78 -f 67/67/92 84/115/101 68/68/79 -f 75/75/78 92/123/102 76/76/80 -f 68/68/79 85/116/103 69/69/81 -f 77/77/82 92/123/102 93/124/104 -f 69/69/81 86/117/105 70/70/83 -f 77/77/82 94/125/106 78/78/84 -f 71/71/85 86/117/105 87/118/107 -f 91/122/100 107/138/108 92/123/102 -f 84/115/101 100/131/109 85/116/103 -f 93/124/104 107/138/108 108/139/110 -f 85/116/103 101/132/111 86/117/105 -f 93/124/104 109/140/112 94/125/106 -f 87/118/107 101/132/111 102/133/113 -f 95/126/93 109/140/112 110/141/114 -f 87/118/107 103/134/115 88/119/94 -f 96/127/95 110/141/114 111/142/116 -f 89/120/96 103/134/115 104/135/117 -f 96/127/95 112/143/118 97/128/97 -f 90/121/98 104/135/117 105/136/119 -f 83/114/99 82/88/16 98/129/120 -f 308/345/18 97/128/97 112/143/118 -f 90/121/98 106/137/121 91/122/100 -f 84/115/101 98/129/120 99/130/122 -f 110/141/114 126/157/123 111/142/116 -f 104/135/117 118/149/124 119/150/125 -f 111/142/116 127/158/126 112/143/118 -f 105/136/119 119/150/125 120/151/127 -f 98/129/120 82/89/16 113/144/128 -f 308/346/18 112/143/118 127/158/126 -f 105/136/119 121/152/129 106/137/121 -f 99/130/122 113/144/128 114/145/130 -f 106/137/121 122/153/131 107/138/108 -f 99/130/122 115/146/132 100/131/109 -f 108/139/110 122/153/131 123/154/133 -f 100/131/109 116/147/134 101/132/111 -f 108/139/110 124/155/135 109/140/112 -f 102/133/113 116/147/134 117/148/136 -f 110/141/114 124/155/135 125/156/137 -f 102/133/113 118/149/124 103/134/115 -f 114/145/130 130/161/138 115/146/132 -f 123/154/133 137/168/139 138/169/140 -f 115/146/132 131/162/141 116/147/134 -f 123/154/133 139/170/142 124/155/135 -f 117/148/136 131/162/141 132/163/143 -f 125/156/137 139/170/142 140/171/144 -f 117/148/136 133/164/145 118/149/124 -f 125/156/137 141/172/146 126/157/123 -f 119/150/125 133/164/145 134/165/147 -f 126/157/123 142/173/148 127/158/126 -f 120/151/127 134/165/147 135/166/149 -f 113/144/128 82/90/16 128/159/150 -f 308/347/18 127/158/126 142/173/148 -f 120/151/127 136/167/151 121/152/129 -f 113/144/128 129/160/152 114/145/130 -f 121/152/129 137/168/139 122/153/131 -f 134/165/147 148/179/153 149/180/154 -f 142/173/148 156/187/155 157/188/156 -f 135/166/149 149/180/154 150/181/157 -f 128/159/150 82/91/16 143/174/158 -f 308/348/18 142/173/148 157/188/156 -f 135/166/149 151/182/159 136/167/151 -f 128/159/150 144/175/160 129/160/152 -f 136/167/151 152/183/161 137/168/139 -f 130/161/138 144/175/160 145/176/162 -f 138/169/140 152/183/161 153/184/163 -f 130/161/138 146/177/164 131/162/141 -f 138/169/140 154/185/165 139/170/142 -f 132/163/143 146/177/164 147/178/166 -f 140/171/144 154/185/165 155/186/167 -f 132/163/143 148/179/153 133/164/145 -f 140/171/144 156/187/155 141/172/146 -f 153/184/163 167/198/168 168/199/169 -f 145/176/162 161/192/170 146/177/164 -f 153/184/163 169/200/171 154/185/165 -f 147/178/166 161/192/170 162/193/172 -f 155/186/167 169/200/171 170/201/173 -f 147/178/166 163/194/174 148/179/153 -f 155/186/167 171/202/175 156/187/155 -f 149/180/154 163/194/174 164/195/176 -f 156/187/155 172/203/177 157/188/156 -f 150/181/157 164/195/176 165/196/178 -f 143/174/158 82/92/16 158/189/179 -f 308/349/18 157/188/156 172/203/177 -f 150/181/157 166/197/180 151/182/159 -f 143/174/158 159/190/181 144/175/160 -f 151/182/159 167/198/168 152/183/161 -f 145/176/162 159/190/181 160/191/182 -f 172/203/177 186/217/183 187/218/184 -f 165/196/178 179/210/185 180/211/186 -f 158/189/179 82/93/16 173/204/187 -f 308/350/18 172/203/177 187/218/184 -f 165/196/178 181/212/188 166/197/180 -f 158/189/179 174/205/189 159/190/181 -f 166/197/180 182/213/190 167/198/168 -f 159/190/181 175/206/191 160/191/182 -f 168/199/169 182/213/190 183/214/192 -f 160/191/182 176/207/193 161/192/170 -f 168/199/169 184/215/194 169/200/171 -f 162/193/172 176/207/193 177/208/195 -f 169/200/171 185/216/196 170/201/173 -f 162/193/172 178/209/197 163/194/174 -f 171/202/175 185/216/196 186/217/183 -f 164/195/176 178/209/197 179/210/185 -f 175/206/191 191/222/198 176/207/193 -f 183/214/192 199/230/199 184/215/194 -f 177/208/195 191/222/198 192/223/200 -f 185/216/196 199/230/199 200/231/201 -f 177/208/195 193/224/202 178/209/197 -f 185/216/196 201/232/203 186/217/183 -f 179/210/185 193/224/202 194/225/204 -f 186/217/183 202/233/205 187/218/184 -f 180/211/186 194/225/204 195/226/206 -f 173/204/187 82/94/16 188/219/207 -f 308/351/18 187/218/184 202/233/205 -f 180/211/186 196/227/208 181/212/188 -f 174/205/189 188/219/207 189/220/209 -f 181/212/188 197/228/210 182/213/190 -f 175/206/191 189/220/209 190/221/211 -f 183/214/192 197/228/210 198/229/212 -f 195/226/206 209/240/213 210/241/214 -f 188/219/207 82/95/16 203/234/215 -f 308/352/18 202/233/205 217/248/216 -f 195/226/206 211/242/217 196/227/208 -f 188/219/207 204/235/218 189/220/209 -f 196/227/208 212/243/219 197/228/210 -f 189/220/209 205/236/220 190/221/211 -f 198/229/212 212/243/219 213/244/221 -f 190/221/211 206/237/222 191/222/198 -f 198/229/212 214/245/223 199/230/199 -f 192/223/200 206/237/222 207/238/224 -f 200/231/201 214/245/223 215/246/225 -f 192/223/200 208/239/226 193/224/202 -f 200/231/201 216/247/227 201/232/203 -f 194/225/204 208/239/226 209/240/213 -f 201/232/203 217/248/216 202/233/205 -f 213/244/221 229/260/228 214/245/223 -f 207/238/224 221/252/229 222/253/230 -f 215/246/225 229/260/228 230/261/231 -f 207/238/224 223/254/232 208/239/226 -f 215/246/225 231/262/233 216/247/227 -f 209/240/213 223/254/232 224/255/234 -f 216/247/227 232/263/235 217/248/216 -f 210/241/214 224/255/234 225/256/236 -f 203/234/215 82/96/16 218/249/237 -f 308/353/18 217/248/216 232/263/235 -f 210/241/214 226/257/238 211/242/217 -f 203/234/215 219/250/239 204/235/218 -f 211/242/217 227/258/240 212/243/219 -f 204/235/218 220/251/241 205/236/220 -f 213/244/221 227/258/240 228/259/242 -f 205/236/220 221/252/229 206/237/222 -f 308/354/18 232/263/235 247/278/243 -f 225/256/236 241/272/244 226/257/238 -f 218/249/237 234/265/245 219/250/239 -f 226/257/238 242/273/246 227/258/240 -f 220/251/241 234/265/245 235/266/247 -f 228/259/242 242/273/246 243/274/248 -f 220/251/241 236/267/249 221/252/229 -f 228/259/242 244/275/250 229/260/228 -f 222/253/230 236/267/249 237/268/251 -f 230/261/231 244/275/250 245/276/252 -f 222/253/230 238/269/253 223/254/232 -f 230/261/231 246/277/254 231/262/233 -f 224/255/234 238/269/253 239/270/255 -f 232/263/235 246/277/254 247/278/243 -f 225/256/236 239/270/255 240/271/256 -f 218/249/237 82/97/16 233/264/257 -f 245/276/252 259/290/258 260/291/259 -f 237/268/251 253/284/260 238/269/253 -f 245/276/252 261/292/261 246/277/254 -f 239/270/255 253/284/260 254/285/262 -f 246/277/254 262/293/263 247/278/243 -f 240/271/256 254/285/262 255/286/264 -f 233/264/257 82/98/16 248/279/265 -f 308/355/18 247/278/243 262/293/263 -f 240/271/256 256/287/266 241/272/244 -f 233/264/257 249/280/267 234/265/245 -f 241/272/244 257/288/268 242/273/246 -f 234/265/245 250/281/269 235/266/247 -f 243/274/248 257/288/268 258/289/270 -f 235/266/247 251/282/271 236/267/249 -f 243/274/248 259/290/258 244/275/250 -f 237/268/251 251/282/271 252/283/272 -f 249/280/267 263/294/273 264/295/274 -f 256/287/266 272/303/275 257/288/268 -f 249/280/267 265/296/276 250/281/269 -f 258/289/270 272/303/275 273/304/277 -f 250/281/269 266/297/278 251/282/271 -f 258/289/270 274/305/279 259/290/258 -f 252/283/272 266/297/278 267/298/280 -f 260/291/259 274/305/279 275/306/281 -f 252/283/272 268/299/282 253/284/260 -f 260/291/259 276/307/283 261/292/261 -f 254/285/262 268/299/282 269/300/284 -f 261/292/261 277/308/285 262/293/263 -f 255/286/264 269/300/284 270/301/286 -f 248/279/265 82/99/16 263/294/273 -f 308/356/18 262/293/263 277/308/285 -f 255/286/264 271/302/287 256/287/266 -f 267/298/280 283/314/288 268/299/282 -f 275/306/281 291/322/289 276/307/283 -f 269/300/284 283/314/288 284/315/290 -f 277/308/285 291/322/289 292/323/291 -f 270/301/286 284/315/290 285/316/292 -f 263/294/273 82/100/16 278/309/293 -f 308/357/18 277/308/285 292/323/291 -f 270/301/286 286/317/294 271/302/287 -f 264/295/274 278/309/293 279/310/295 -f 271/302/287 287/318/296 272/303/275 -f 264/295/274 280/311/297 265/296/276 -f 273/304/277 287/318/296 288/319/298 -f 265/296/276 281/312/299 266/297/278 -f 273/304/277 289/320/300 274/305/279 -f 267/298/280 281/312/299 282/313/301 -f 275/306/281 289/320/300 290/321/302 -f 286/317/294 302/333/303 287/318/296 -f 279/310/295 295/326/304 280/311/297 -f 288/319/298 302/333/303 303/334/305 -f 280/311/297 296/327/306 281/312/299 -f 288/319/298 304/335/307 289/320/300 -f 282/313/301 296/327/306 297/328/308 -f 290/321/302 304/335/307 305/336/309 -f 282/313/301 298/329/310 283/314/288 -f 290/321/302 306/337/311 291/322/289 -f 284/315/290 298/329/310 299/330/312 -f 292/323/291 306/337/311 307/338/313 -f 285/316/292 299/330/312 300/331/314 -f 278/309/293 82/101/16 293/324/315 -f 308/358/18 292/323/291 307/338/313 -f 285/316/292 301/332/316 286/317/294 -f 278/309/293 294/325/317 279/310/295 -f 305/336/309 322/384/318 306/337/311 -f 299/330/312 314/376/319 315/377/320 -f 306/337/311 323/385/321 307/338/313 -f 300/331/314 315/377/320 316/378/322 -f 293/324/315 82/102/16 309/371/323 -f 308/359/18 307/338/313 323/385/321 -f 300/331/314 317/379/324 301/332/316 -f 293/324/315 310/372/325 294/325/317 -f 301/332/316 318/380/326 302/333/303 -f 294/325/317 311/373/327 295/326/304 -f 303/334/305 318/380/326 319/381/328 -f 295/326/304 312/374/329 296/327/306 -f 303/334/305 320/382/330 304/335/307 -f 297/328/308 312/374/329 313/375/331 -f 305/336/309 320/382/330 321/383/332 -f 297/328/308 314/376/319 298/329/310 -f 310/372/325 326/388/333 311/373/327 -f 319/381/328 333/395/334 334/396/335 -f 311/373/327 327/389/336 312/374/329 -f 319/381/328 335/397/337 320/382/330 -f 312/374/329 328/390/338 313/375/331 -f 321/383/332 335/397/337 336/398/339 -f 313/375/331 329/391/340 314/376/319 -f 321/383/332 337/399/341 322/384/318 -f 315/377/320 329/391/340 330/392/342 -f 322/384/318 338/400/343 323/385/321 -f 316/378/322 330/392/342 331/393/344 -f 309/371/323 82/103/16 324/386/345 -f 308/360/18 323/385/321 338/400/343 -f 316/378/322 332/394/346 317/379/324 -f 309/371/323 325/387/347 310/372/325 -f 317/379/324 333/395/334 318/380/326 -f 330/392/342 344/406/348 345/407/349 -f 337/399/341 353/415/350 338/400/343 -f 331/393/344 345/407/349 346/408/351 -f 324/386/345 82/104/16 339/401/352 -f 308/361/18 338/400/343 353/415/350 -f 331/393/344 347/409/353 332/394/346 -f 324/386/345 340/402/354 325/387/347 -f 332/394/346 348/410/355 333/395/334 -f 325/387/347 341/403/356 326/388/333 -f 334/396/335 348/410/355 349/411/357 -f 326/388/333 342/404/358 327/389/336 -f 334/396/335 350/412/359 335/397/337 -f 328/390/338 342/404/358 343/405/360 -f 336/398/339 350/412/359 351/413/361 -f 328/390/338 344/406/348 329/391/340 -f 336/398/339 352/414/362 337/399/341 -f 349/411/357 363/434/363 364/436/364 -f 341/403/356 357/422/365 342/404/358 -f 349/411/357 365/438/366 350/412/359 -f 343/405/360 357/422/365 358/424/367 -f 351/413/361 365/438/366 366/440/368 -f 343/405/360 359/426/369 344/406/348 -f 351/413/361 367/442/370 352/414/362 -f 345/407/349 359/426/369 360/428/371 -f 352/414/362 368/445/372 353/415/350 -f 346/408/351 360/428/371 361/430/373 -f 339/401/352 82/105/16 354/416/374 -f 308/362/18 353/415/350 368/445/372 -f 346/408/351 362/432/375 347/409/353 -f 339/401/352 355/418/376 340/402/354 -f 347/409/353 363/434/363 348/410/355 -f 341/403/356 355/418/376 356/420/377 -f 367/443/370 383/460/378 368/444/372 -f 361/431/373 375/452/379 376/453/380 -f 354/417/374 82/106/16 369/446/381 -f 308/363/18 368/444/372 383/460/378 -f 361/431/373 377/454/382 362/433/375 -f 354/417/374 370/447/383 355/419/376 -f 362/433/375 378/455/384 363/435/363 -f 356/421/377 370/447/383 371/448/385 -f 364/437/364 378/455/384 379/456/386 -f 356/421/377 372/449/387 357/423/365 -f 364/437/364 380/457/388 365/439/366 -f 358/425/367 372/449/387 373/450/389 -f 366/441/368 380/457/388 381/458/390 -f 358/425/367 374/451/391 359/427/369 -f 366/441/368 382/459/392 367/443/370 -f 360/429/371 374/451/391 375/452/379 -f 379/456/386 395/472/393 380/457/388 -f 373/450/389 387/464/394 388/465/395 -f 381/458/390 395/472/393 396/473/396 -f 373/450/389 389/466/397 374/451/391 -f 381/458/390 397/474/398 382/459/392 -f 375/452/379 389/466/397 390/467/399 -f 382/459/392 398/475/400 383/460/378 -f 376/453/380 390/467/399 391/468/401 -f 369/446/381 82/107/16 384/461/402 -f 308/364/18 383/460/378 398/475/400 -f 376/453/380 392/469/403 377/454/382 -f 369/446/381 385/462/404 370/447/383 -f 377/454/382 393/470/405 378/455/384 -f 371/448/385 385/462/404 386/463/406 -f 379/456/386 393/470/405 394/471/407 -f 371/448/385 387/464/394 372/449/387 -f 384/461/402 82/108/16 399/476/408 -f 308/365/18 398/475/400 413/490/409 -f 391/468/401 407/484/410 392/469/403 -f 385/462/404 399/476/408 400/477/411 -f 392/469/403 408/485/412 393/470/405 -f 385/462/404 401/478/413 386/463/406 -f 394/471/407 408/485/412 409/486/414 -f 386/463/406 402/479/415 387/464/394 -f 394/471/407 410/487/416 395/472/393 -f 388/465/395 402/479/415 403/480/417 -f 396/473/396 410/487/416 411/488/418 -f 388/465/395 404/481/419 389/466/397 -f 397/474/398 411/488/418 412/489/420 -f 390/467/399 404/481/419 405/482/421 -f 397/474/398 413/490/409 398/475/400 -f 391/468/401 405/482/421 406/483/422 -f 403/480/417 417/494/423 418/495/424 -f 411/488/418 425/502/425 426/503/426 -f 403/480/417 419/496/427 404/481/419 -f 411/488/418 427/504/428 412/489/420 -f 405/482/421 419/496/427 420/497/429 -f 412/489/420 428/505/430 413/490/409 -f 406/483/422 420/497/429 421/498/431 -f 399/476/408 82/109/16 414/491/432 -f 308/366/18 413/490/409 428/505/430 -f 406/483/422 422/499/433 407/484/410 -f 399/476/408 415/492/434 400/477/411 -f 407/484/410 423/500/435 408/485/412 -f 401/478/413 415/492/434 416/493/436 -f 409/486/414 423/500/435 424/501/437 -f 401/478/413 417/494/423 402/479/415 -f 409/486/414 425/502/425 410/487/416 -f 421/498/431 437/514/438 422/499/433 -f 414/491/432 430/507/439 415/492/434 -f 422/499/433 438/515/440 423/500/435 -f 416/493/436 430/507/439 431/508/441 -f 424/501/437 438/515/440 439/516/442 -f 416/493/436 432/509/443 417/494/423 -f 424/501/437 440/517/444 425/502/425 -f 418/495/424 432/509/443 433/510/445 -f 426/503/426 440/517/444 441/518/446 -f 418/495/424 434/511/447 419/496/427 -f 426/503/426 442/519/448 427/504/428 -f 420/497/429 434/511/447 435/512/449 -f 427/504/428 443/520/450 428/505/430 -f 421/498/431 435/512/449 436/513/451 -f 414/491/432 82/110/16 429/506/452 -f 308/367/18 428/505/430 443/520/450 -f 441/518/446 455/532/453 456/533/454 -f 433/510/445 449/526/455 434/511/447 -f 441/518/446 457/534/456 442/519/448 -f 435/512/449 449/526/455 450/527/457 -f 442/519/448 458/535/458 443/520/450 -f 436/513/451 450/527/457 451/528/459 -f 429/506/452 82/111/16 444/521/460 -f 308/368/18 443/520/450 458/535/458 -f 436/513/451 452/529/461 437/514/438 -f 430/507/439 444/521/460 445/522/462 -f 437/514/438 453/530/463 438/515/440 -f 430/507/439 446/523/464 431/508/441 -f 439/516/442 453/530/463 454/531/465 -f 431/508/441 447/524/466 432/509/443 -f 439/516/442 455/532/453 440/517/444 -f 433/510/445 447/524/466 448/525/467 -f 444/521/460 460/537/468 445/522/462 -f 452/529/461 468/545/469 453/530/463 -f 446/523/464 460/537/468 461/538/470 -f 454/531/465 468/545/469 469/546/471 -f 446/523/464 462/539/472 447/524/466 -f 454/531/465 470/547/473 455/532/453 -f 448/525/467 462/539/472 463/540/474 -f 456/533/454 470/547/473 471/548/475 -f 448/525/467 464/541/476 449/526/455 -f 456/533/454 472/549/477 457/534/456 -f 450/527/457 464/541/476 465/542/478 -f 458/535/458 472/549/477 473/550/479 -f 451/528/459 465/542/478 466/543/480 -f 444/521/460 82/112/16 459/536/481 -f 308/369/18 458/535/458 473/550/479 -f 451/528/459 467/544/482 452/529/461 -f 464/541/476 2/2/32 477/554/4 -f 471/548/475 481/558/8 472/549/477 -f 465/542/478 477/554/4 3/3/9 -f 472/549/477 482/559/12 473/550/479 -f 466/543/480 3/3/9 4/4/14 -f 459/536/481 82/113/16 474/551/15 -f 308/370/18 473/550/479 482/559/12 -f 466/543/480 5/5/20 467/544/482 -f 460/537/468 474/551/15 475/552/21 -f 467/544/482 478/555/24 468/545/469 -f 461/538/470 475/552/21 1/1/25 -f 468/545/469 6/6/28 469/546/471 -f 462/539/472 1/1/25 476/553/29 -f 469/546/471 479/556/1 470/547/473 -f 463/540/474 476/553/29 2/2/32 -f 471/548/475 479/556/1 480/557/3 -f 479/556/1 18/18/31 19/19/2 -f 477/554/4 2/2/32 11/11/5 -f 480/557/3 19/19/2 20/20/7 -f 3/3/9 477/554/4 12/12/6 -f 481/558/8 20/20/7 21/21/11 -f 3/3/9 13/13/10 14/14/13 -f 4/4/14 14/14/13 15/15/19 -f 475/552/21 474/551/15 7/7/17 -f 5/5/20 15/15/19 16/16/23 -f 1/1/25 475/552/21 8/8/22 -f 478/555/24 16/16/23 17/17/27 -f 476/553/29 1/1/25 9/9/26 -f 6/6/28 17/17/27 18/18/31 -f 2/2/32 476/553/29 10/10/30 -f 17/17/27 32/32/46 33/33/33 -f 10/10/30 25/25/47 26/26/34 -f 19/19/2 18/18/31 33/33/33 -f 11/11/5 26/26/34 27/27/36 -f 20/20/7 19/19/2 34/34/35 -f 13/13/10 12/12/6 27/27/36 -f 20/20/7 35/35/37 36/36/39 -f 13/13/10 28/28/38 29/29/40 -f 14/14/13 29/29/40 30/30/42 -f 7/7/17 22/22/41 23/23/43 -f 15/15/19 30/30/42 31/31/44 -f 8/8/22 23/23/43 24/24/45 -f 16/16/23 31/31/44 32/32/46 -f 9/9/26 24/24/45 25/25/47 -f 30/30/42 29/29/40 44/44/50 -f 22/22/41 37/37/48 38/38/52 -f 30/30/42 45/45/51 46/46/53 -f 23/23/43 38/38/52 39/39/54 -f 32/32/46 31/31/44 46/46/53 -f 24/24/45 39/39/54 40/40/56 -f 33/33/33 32/32/46 47/47/55 -f 25/25/47 40/40/56 41/41/58 -f 34/34/35 33/33/33 48/48/57 -f 26/26/34 41/41/58 42/42/60 -f 34/34/35 49/49/59 50/50/61 -f 27/27/36 42/42/60 43/43/62 -f 35/35/37 50/50/61 51/51/49 -f 28/28/38 43/43/62 44/44/50 -f 40/40/56 55/55/76 56/56/63 -f 48/48/57 63/63/77 64/64/64 -f 41/41/58 56/56/63 57/57/65 -f 49/49/59 64/64/64 65/65/66 -f 43/43/62 42/42/60 57/57/65 -f 50/50/61 65/65/66 66/66/68 -f 44/44/50 43/43/62 58/58/67 -f 44/44/50 59/59/69 60/60/71 -f 37/37/48 52/52/70 53/53/72 -f 45/45/51 60/60/71 61/61/73 -f 38/38/52 53/53/72 54/54/74 -f 47/47/55 46/46/53 61/61/73 -f 39/39/54 54/54/74 55/55/76 -f 47/47/55 62/62/75 63/63/77 -f 59/59/69 74/74/91 75/75/78 -f 52/52/70 67/67/92 68/68/79 -f 60/60/71 75/75/78 76/76/80 -f 53/53/72 68/68/79 69/69/81 -f 62/62/75 61/61/73 76/76/80 -f 54/54/74 69/69/81 70/70/83 -f 62/62/75 77/77/82 78/78/84 -f 56/56/63 55/55/76 70/70/83 -f 63/63/77 78/78/84 79/79/86 -f 56/56/63 71/71/85 72/72/87 -f 65/65/66 64/64/64 79/79/86 -f 58/58/67 57/57/65 72/72/87 -f 65/65/66 80/80/88 81/81/90 -f 59/59/69 58/58/67 73/73/89 -f 78/78/84 94/125/106 95/126/93 -f 71/71/85 87/118/107 88/119/94 -f 79/79/86 95/126/93 96/127/95 -f 73/73/89 72/72/87 88/119/94 -f 81/81/90 80/80/88 96/127/95 -f 74/74/91 73/73/89 89/120/96 -f 74/74/91 90/121/98 91/122/100 -f 67/67/92 83/114/99 84/115/101 -f 75/75/78 91/122/100 92/123/102 -f 68/68/79 84/115/101 85/116/103 -f 77/77/82 76/76/80 92/123/102 -f 69/69/81 85/116/103 86/117/105 -f 77/77/82 93/124/104 94/125/106 -f 71/71/85 70/70/83 86/117/105 -f 91/122/100 106/137/121 107/138/108 -f 84/115/101 99/130/122 100/131/109 -f 93/124/104 92/123/102 107/138/108 -f 85/116/103 100/131/109 101/132/111 -f 93/124/104 108/139/110 109/140/112 -f 87/118/107 86/117/105 101/132/111 -f 95/126/93 94/125/106 109/140/112 -f 87/118/107 102/133/113 103/134/115 -f 96/127/95 95/126/93 110/141/114 -f 89/120/96 88/119/94 103/134/115 -f 96/127/95 111/142/116 112/143/118 -f 90/121/98 89/120/96 104/135/117 -f 90/121/98 105/136/119 106/137/121 -f 84/115/101 83/114/99 98/129/120 -f 110/141/114 125/156/137 126/157/123 -f 104/135/117 103/134/115 118/149/124 -f 111/142/116 126/157/123 127/158/126 -f 105/136/119 104/135/117 119/150/125 -f 105/136/119 120/151/127 121/152/129 -f 99/130/122 98/129/120 113/144/128 -f 106/137/121 121/152/129 122/153/131 -f 99/130/122 114/145/130 115/146/132 -f 108/139/110 107/138/108 122/153/131 -f 100/131/109 115/146/132 116/147/134 -f 108/139/110 123/154/133 124/155/135 -f 102/133/113 101/132/111 116/147/134 -f 110/141/114 109/140/112 124/155/135 -f 102/133/113 117/148/136 118/149/124 -f 114/145/130 129/160/152 130/161/138 -f 123/154/133 122/153/131 137/168/139 -f 115/146/132 130/161/138 131/162/141 -f 123/154/133 138/169/140 139/170/142 -f 117/148/136 116/147/134 131/162/141 -f 125/156/137 124/155/135 139/170/142 -f 117/148/136 132/163/143 133/164/145 -f 125/156/137 140/171/144 141/172/146 -f 119/150/125 118/149/124 133/164/145 -f 126/157/123 141/172/146 142/173/148 -f 120/151/127 119/150/125 134/165/147 -f 120/151/127 135/166/149 136/167/151 -f 113/144/128 128/159/150 129/160/152 -f 121/152/129 136/167/151 137/168/139 -f 134/165/147 133/164/145 148/179/153 -f 142/173/148 141/172/146 156/187/155 -f 135/166/149 134/165/147 149/180/154 -f 135/166/149 150/181/157 151/182/159 -f 128/159/150 143/174/158 144/175/160 -f 136/167/151 151/182/159 152/183/161 -f 130/161/138 129/160/152 144/175/160 -f 138/169/140 137/168/139 152/183/161 -f 130/161/138 145/176/162 146/177/164 -f 138/169/140 153/184/163 154/185/165 -f 132/163/143 131/162/141 146/177/164 -f 140/171/144 139/170/142 154/185/165 -f 132/163/143 147/178/166 148/179/153 -f 140/171/144 155/186/167 156/187/155 -f 153/184/163 152/183/161 167/198/168 -f 145/176/162 160/191/182 161/192/170 -f 153/184/163 168/199/169 169/200/171 -f 147/178/166 146/177/164 161/192/170 -f 155/186/167 154/185/165 169/200/171 -f 147/178/166 162/193/172 163/194/174 -f 155/186/167 170/201/173 171/202/175 -f 149/180/154 148/179/153 163/194/174 -f 156/187/155 171/202/175 172/203/177 -f 150/181/157 149/180/154 164/195/176 -f 150/181/157 165/196/178 166/197/180 -f 143/174/158 158/189/179 159/190/181 -f 151/182/159 166/197/180 167/198/168 -f 145/176/162 144/175/160 159/190/181 -f 172/203/177 171/202/175 186/217/183 -f 165/196/178 164/195/176 179/210/185 -f 165/196/178 180/211/186 181/212/188 -f 158/189/179 173/204/187 174/205/189 -f 166/197/180 181/212/188 182/213/190 -f 159/190/181 174/205/189 175/206/191 -f 168/199/169 167/198/168 182/213/190 -f 160/191/182 175/206/191 176/207/193 -f 168/199/169 183/214/192 184/215/194 -f 162/193/172 161/192/170 176/207/193 -f 169/200/171 184/215/194 185/216/196 -f 162/193/172 177/208/195 178/209/197 -f 171/202/175 170/201/173 185/216/196 -f 164/195/176 163/194/174 178/209/197 -f 175/206/191 190/221/211 191/222/198 -f 183/214/192 198/229/212 199/230/199 -f 177/208/195 176/207/193 191/222/198 -f 185/216/196 184/215/194 199/230/199 -f 177/208/195 192/223/200 193/224/202 -f 185/216/196 200/231/201 201/232/203 -f 179/210/185 178/209/197 193/224/202 -f 186/217/183 201/232/203 202/233/205 -f 180/211/186 179/210/185 194/225/204 -f 180/211/186 195/226/206 196/227/208 -f 174/205/189 173/204/187 188/219/207 -f 181/212/188 196/227/208 197/228/210 -f 175/206/191 174/205/189 189/220/209 -f 183/214/192 182/213/190 197/228/210 -f 195/226/206 194/225/204 209/240/213 -f 195/226/206 210/241/214 211/242/217 -f 188/219/207 203/234/215 204/235/218 -f 196/227/208 211/242/217 212/243/219 -f 189/220/209 204/235/218 205/236/220 -f 198/229/212 197/228/210 212/243/219 -f 190/221/211 205/236/220 206/237/222 -f 198/229/212 213/244/221 214/245/223 -f 192/223/200 191/222/198 206/237/222 -f 200/231/201 199/230/199 214/245/223 -f 192/223/200 207/238/224 208/239/226 -f 200/231/201 215/246/225 216/247/227 -f 194/225/204 193/224/202 208/239/226 -f 201/232/203 216/247/227 217/248/216 -f 213/244/221 228/259/242 229/260/228 -f 207/238/224 206/237/222 221/252/229 -f 215/246/225 214/245/223 229/260/228 -f 207/238/224 222/253/230 223/254/232 -f 215/246/225 230/261/231 231/262/233 -f 209/240/213 208/239/226 223/254/232 -f 216/247/227 231/262/233 232/263/235 -f 210/241/214 209/240/213 224/255/234 -f 210/241/214 225/256/236 226/257/238 -f 203/234/215 218/249/237 219/250/239 -f 211/242/217 226/257/238 227/258/240 -f 204/235/218 219/250/239 220/251/241 -f 213/244/221 212/243/219 227/258/240 -f 205/236/220 220/251/241 221/252/229 -f 225/256/236 240/271/256 241/272/244 -f 218/249/237 233/264/257 234/265/245 -f 226/257/238 241/272/244 242/273/246 -f 220/251/241 219/250/239 234/265/245 -f 228/259/242 227/258/240 242/273/246 -f 220/251/241 235/266/247 236/267/249 -f 228/259/242 243/274/248 244/275/250 -f 222/253/230 221/252/229 236/267/249 -f 230/261/231 229/260/228 244/275/250 -f 222/253/230 237/268/251 238/269/253 -f 230/261/231 245/276/252 246/277/254 -f 224/255/234 223/254/232 238/269/253 -f 232/263/235 231/262/233 246/277/254 -f 225/256/236 224/255/234 239/270/255 -f 245/276/252 244/275/250 259/290/258 -f 237/268/251 252/283/272 253/284/260 -f 245/276/252 260/291/259 261/292/261 -f 239/270/255 238/269/253 253/284/260 -f 246/277/254 261/292/261 262/293/263 -f 240/271/256 239/270/255 254/285/262 -f 240/271/256 255/286/264 256/287/266 -f 233/264/257 248/279/265 249/280/267 -f 241/272/244 256/287/266 257/288/268 -f 234/265/245 249/280/267 250/281/269 -f 243/274/248 242/273/246 257/288/268 -f 235/266/247 250/281/269 251/282/271 -f 243/274/248 258/289/270 259/290/258 -f 237/268/251 236/267/249 251/282/271 -f 249/280/267 248/279/265 263/294/273 -f 256/287/266 271/302/287 272/303/275 -f 249/280/267 264/295/274 265/296/276 -f 258/289/270 257/288/268 272/303/275 -f 250/281/269 265/296/276 266/297/278 -f 258/289/270 273/304/277 274/305/279 -f 252/283/272 251/282/271 266/297/278 -f 260/291/259 259/290/258 274/305/279 -f 252/283/272 267/298/280 268/299/282 -f 260/291/259 275/306/281 276/307/283 -f 254/285/262 253/284/260 268/299/282 -f 261/292/261 276/307/283 277/308/285 -f 255/286/264 254/285/262 269/300/284 -f 255/286/264 270/301/286 271/302/287 -f 267/298/280 282/313/301 283/314/288 -f 275/306/281 290/321/302 291/322/289 -f 269/300/284 268/299/282 283/314/288 -f 277/308/285 276/307/283 291/322/289 -f 270/301/286 269/300/284 284/315/290 -f 270/301/286 285/316/292 286/317/294 -f 264/295/274 263/294/273 278/309/293 -f 271/302/287 286/317/294 287/318/296 -f 264/295/274 279/310/295 280/311/297 -f 273/304/277 272/303/275 287/318/296 -f 265/296/276 280/311/297 281/312/299 -f 273/304/277 288/319/298 289/320/300 -f 267/298/280 266/297/278 281/312/299 -f 275/306/281 274/305/279 289/320/300 -f 286/317/294 301/332/316 302/333/303 -f 279/310/295 294/325/317 295/326/304 -f 288/319/298 287/318/296 302/333/303 -f 280/311/297 295/326/304 296/327/306 -f 288/319/298 303/334/305 304/335/307 -f 282/313/301 281/312/299 296/327/306 -f 290/321/302 289/320/300 304/335/307 -f 282/313/301 297/328/308 298/329/310 -f 290/321/302 305/336/309 306/337/311 -f 284/315/290 283/314/288 298/329/310 -f 292/323/291 291/322/289 306/337/311 -f 285/316/292 284/315/290 299/330/312 -f 285/316/292 300/331/314 301/332/316 -f 278/309/293 293/324/315 294/325/317 -f 305/336/309 321/383/332 322/384/318 -f 299/330/312 298/329/310 314/376/319 -f 306/337/311 322/384/318 323/385/321 -f 300/331/314 299/330/312 315/377/320 -f 300/331/314 316/378/322 317/379/324 -f 293/324/315 309/371/323 310/372/325 -f 301/332/316 317/379/324 318/380/326 -f 294/325/317 310/372/325 311/373/327 -f 303/334/305 302/333/303 318/380/326 -f 295/326/304 311/373/327 312/374/329 -f 303/334/305 319/381/328 320/382/330 -f 297/328/308 296/327/306 312/374/329 -f 305/336/309 304/335/307 320/382/330 -f 297/328/308 313/375/331 314/376/319 -f 310/372/325 325/387/347 326/388/333 -f 319/381/328 318/380/326 333/395/334 -f 311/373/327 326/388/333 327/389/336 -f 319/381/328 334/396/335 335/397/337 -f 312/374/329 327/389/336 328/390/338 -f 321/383/332 320/382/330 335/397/337 -f 313/375/331 328/390/338 329/391/340 -f 321/383/332 336/398/339 337/399/341 -f 315/377/320 314/376/319 329/391/340 -f 322/384/318 337/399/341 338/400/343 -f 316/378/322 315/377/320 330/392/342 -f 316/378/322 331/393/344 332/394/346 -f 309/371/323 324/386/345 325/387/347 -f 317/379/324 332/394/346 333/395/334 -f 330/392/342 329/391/340 344/406/348 -f 337/399/341 352/414/362 353/415/350 -f 331/393/344 330/392/342 345/407/349 -f 331/393/344 346/408/351 347/409/353 -f 324/386/345 339/401/352 340/402/354 -f 332/394/346 347/409/353 348/410/355 -f 325/387/347 340/402/354 341/403/356 -f 334/396/335 333/395/334 348/410/355 -f 326/388/333 341/403/356 342/404/358 -f 334/396/335 349/411/357 350/412/359 -f 328/390/338 327/389/336 342/404/358 -f 336/398/339 335/397/337 350/412/359 -f 328/390/338 343/405/360 344/406/348 -f 336/398/339 351/413/361 352/414/362 -f 349/411/357 348/410/355 363/434/363 -f 341/403/356 356/420/377 357/422/365 -f 349/411/357 364/436/364 365/438/366 -f 343/405/360 342/404/358 357/422/365 -f 351/413/361 350/412/359 365/438/366 -f 343/405/360 358/424/367 359/426/369 -f 351/413/361 366/440/368 367/442/370 -f 345/407/349 344/406/348 359/426/369 -f 352/414/362 367/442/370 368/445/372 -f 346/408/351 345/407/349 360/428/371 -f 346/408/351 361/430/373 362/432/375 -f 339/401/352 354/416/374 355/418/376 -f 347/409/353 362/432/375 363/434/363 -f 341/403/356 340/402/354 355/418/376 -f 367/443/370 382/459/392 383/460/378 -f 361/431/373 360/429/371 375/452/379 -f 361/431/373 376/453/380 377/454/382 -f 354/417/374 369/446/381 370/447/383 -f 362/433/375 377/454/382 378/455/384 -f 356/421/377 355/419/376 370/447/383 -f 364/437/364 363/435/363 378/455/384 -f 356/421/377 371/448/385 372/449/387 -f 364/437/364 379/456/386 380/457/388 -f 358/425/367 357/423/365 372/449/387 -f 366/441/368 365/439/366 380/457/388 -f 358/425/367 373/450/389 374/451/391 -f 366/441/368 381/458/390 382/459/392 -f 360/429/371 359/427/369 374/451/391 -f 379/456/386 394/471/407 395/472/393 -f 373/450/389 372/449/387 387/464/394 -f 381/458/390 380/457/388 395/472/393 -f 373/450/389 388/465/395 389/466/397 -f 381/458/390 396/473/396 397/474/398 -f 375/452/379 374/451/391 389/466/397 -f 382/459/392 397/474/398 398/475/400 -f 376/453/380 375/452/379 390/467/399 -f 376/453/380 391/468/401 392/469/403 -f 369/446/381 384/461/402 385/462/404 -f 377/454/382 392/469/403 393/470/405 -f 371/448/385 370/447/383 385/462/404 -f 379/456/386 378/455/384 393/470/405 -f 371/448/385 386/463/406 387/464/394 -f 391/468/401 406/483/422 407/484/410 -f 385/462/404 384/461/402 399/476/408 -f 392/469/403 407/484/410 408/485/412 -f 385/462/404 400/477/411 401/478/413 -f 394/471/407 393/470/405 408/485/412 -f 386/463/406 401/478/413 402/479/415 -f 394/471/407 409/486/414 410/487/416 -f 388/465/395 387/464/394 402/479/415 -f 396/473/396 395/472/393 410/487/416 -f 388/465/395 403/480/417 404/481/419 -f 397/474/398 396/473/396 411/488/418 -f 390/467/399 389/466/397 404/481/419 -f 397/474/398 412/489/420 413/490/409 -f 391/468/401 390/467/399 405/482/421 -f 403/480/417 402/479/415 417/494/423 -f 411/488/418 410/487/416 425/502/425 -f 403/480/417 418/495/424 419/496/427 -f 411/488/418 426/503/426 427/504/428 -f 405/482/421 404/481/419 419/496/427 -f 412/489/420 427/504/428 428/505/430 -f 406/483/422 405/482/421 420/497/429 -f 406/483/422 421/498/431 422/499/433 -f 399/476/408 414/491/432 415/492/434 -f 407/484/410 422/499/433 423/500/435 -f 401/478/413 400/477/411 415/492/434 -f 409/486/414 408/485/412 423/500/435 -f 401/478/413 416/493/436 417/494/423 -f 409/486/414 424/501/437 425/502/425 -f 421/498/431 436/513/451 437/514/438 -f 414/491/432 429/506/452 430/507/439 -f 422/499/433 437/514/438 438/515/440 -f 416/493/436 415/492/434 430/507/439 -f 424/501/437 423/500/435 438/515/440 -f 416/493/436 431/508/441 432/509/443 -f 424/501/437 439/516/442 440/517/444 -f 418/495/424 417/494/423 432/509/443 -f 426/503/426 425/502/425 440/517/444 -f 418/495/424 433/510/445 434/511/447 -f 426/503/426 441/518/446 442/519/448 -f 420/497/429 419/496/427 434/511/447 -f 427/504/428 442/519/448 443/520/450 -f 421/498/431 420/497/429 435/512/449 -f 441/518/446 440/517/444 455/532/453 -f 433/510/445 448/525/467 449/526/455 -f 441/518/446 456/533/454 457/534/456 -f 435/512/449 434/511/447 449/526/455 -f 442/519/448 457/534/456 458/535/458 -f 436/513/451 435/512/449 450/527/457 -f 436/513/451 451/528/459 452/529/461 -f 430/507/439 429/506/452 444/521/460 -f 437/514/438 452/529/461 453/530/463 -f 430/507/439 445/522/462 446/523/464 -f 439/516/442 438/515/440 453/530/463 -f 431/508/441 446/523/464 447/524/466 -f 439/516/442 454/531/465 455/532/453 -f 433/510/445 432/509/443 447/524/466 -f 444/521/460 459/536/481 460/537/468 -f 452/529/461 467/544/482 468/545/469 -f 446/523/464 445/522/462 460/537/468 -f 454/531/465 453/530/463 468/545/469 -f 446/523/464 461/538/470 462/539/472 -f 454/531/465 469/546/471 470/547/473 -f 448/525/467 447/524/466 462/539/472 -f 456/533/454 455/532/453 470/547/473 -f 448/525/467 463/540/474 464/541/476 -f 456/533/454 471/548/475 472/549/477 -f 450/527/457 449/526/455 464/541/476 -f 458/535/458 457/534/456 472/549/477 -f 451/528/459 450/527/457 465/542/478 -f 451/528/459 466/543/480 467/544/482 -f 464/541/476 463/540/474 2/2/32 -f 471/548/475 480/557/3 481/558/8 -f 465/542/478 464/541/476 477/554/4 -f 472/549/477 481/558/8 482/559/12 -f 466/543/480 465/542/478 3/3/9 -f 466/543/480 4/4/14 5/5/20 -f 460/537/468 459/536/481 474/551/15 -f 467/544/482 5/5/20 478/555/24 -f 461/538/470 460/537/468 475/552/21 -f 468/545/469 478/555/24 6/6/28 -f 462/539/472 461/538/470 1/1/25 -f 469/546/471 6/6/28 479/556/1 -f 463/540/474 462/539/472 476/553/29 -f 471/548/475 470/547/473 479/556/1