diff --git a/docs/接口2-C端生发-技术实现方案.md b/docs/接口2-C端生发-技术实现方案.md new file mode 100644 index 0000000..83d1f71 --- /dev/null +++ b/docs/接口2-C端生发-技术实现方案.md @@ -0,0 +1,246 @@ +# 接口 2:C 端生发 — 技术实现方案(第一步:发际线遮罩渲染) + +> 在 **高性能 worker(GPU 机)** 上实现,与接口 1 同机。对外接口经网关代理(见 [`系统架构-网关与高性能后端.md`](系统架构-网关与高性能后端.md))。 +> 发际线检测算法移植自 **head3d** 项目(已实现 502 点 mesh + UV 贴图方案)。 + +--- + +## 0. 本期范围(第一步) + +接口 2 输入用户正面照 + **性别**,按性别对应的发际线类型贴图,**逐张把发际线曲线渲染到照片上**,输出多张「叠加了建议发际线的预览图」,按固定顺序返回。 + +- **本期只做「渲染遮罩/预览图」**,不做真正的文生图生发(那是后续步骤)。当前 `image_url` 返回的是「原照片 + 发际线曲线叠加图」。 +- 排序 `order` 本期不计算,按贴图顺序 `1..N`。 + +--- + +## 1. 与现接口文档的差异(接口 2 需同步更新 `接口文档.md`) + +| 项 | 现状 | 本期改为 | +|----|------|----------| +| 输入参数 | `beauty_enabled` | **新增必填 `gender`(`male`/`female`)**;`beauty_enabled` 保留但本期不生效 | +| 输出 `results[]` 数量 | Mock 2 个 | = 该性别的贴图数量(**female 5 张 / male 4 张**) | +| `results[].image_url` | 生发后图片 | **本期 = 发际线曲线叠加在原照片上的预览图** | +| `results[].hairline_type` | 中文(花瓣形…) | **英文 key**(`flower`/`wave`/`heart`/`ellipse`/`straight`/`m`/`inverse_arc`) | +| `results[].order` | 排序 | 本期固定 `1..N`(不排序) | +| 错误码 1004(性别判断异常) | 待确认 | `gender` 改为必填入参 → **不再自动判别性别**;1004 仅在 `gender` 非法值时使用(或弃用) | + +> ⚠️ 这是接口 2 的**有意契约变更**(加入参 + 改输出语义),需在 `接口文档.md` 接口 2 章节同步。其余 4 个接口契约不变。 + +### gender → 贴图集合 + +`hairline_texture/` 目录下贴图(512×512 RGBA,白色发际线曲线在顶部 UV 条带): + +| gender | 贴图文件 | hairline_type (key) | +|--------|----------|---------------------| +| female | `girl_ellipse.png` | `ellipse` | +| female | `girl_flower.png` | `flower` | +| female | `girl_heart.png` | `heart` | +| female | `girl_straight.png` | `straight` | +| female | `girl_wave.png` | `wave` | +| male | `man_ellipse.png` | `ellipse` | +| male | `man_m.png` | `m` | +| male | `man_straight.png` | `straight` | +| male | `man_ inverse_arc.png` | `inverse_arc` | + +> 注意 `man_ inverse_arc.png` 文件名里有个空格,代码里按 `gender + '_' + key` 生成文件名时需保留/清洗一致。建议**启动时扫描目录**建立 `{gender: [(key, path)]}` 映射,而不是硬编码文件名,并把文件名规范化(去空格)。 + +--- + +## 2. 已从 head3d 复制到本项目的文件 + +全部放在 `hairline/` 包下(已复制,agent 直接用): + +``` +hairline/ +├── __init__.py +├── constants.py # 17 锚点、UV 偏移、分割类别、矢状-arc 常量、HF 模型 id +├── obj_io.py # OBJ 读写 +├── face_landmarks.py # MediaPipe Tasks FaceLandmarker 封装(用 face_landmarker.task) +├── face_parsing.py # SegFormer 人脸分割封装 +├── hairline_2d.py # 射线检测发际线 2D + 平滑 + 回退 +├── lift_3d.py # 2D→3D 矢状-arc 提升 + 中间行 + assemble 502 点 +├── extract_hairline.py # 主管线(image → 502 点),可复用 run() +├── _index_map_data.py # 468→OBJ indexMap(build_extended_obj 用,本期渲染不需要) +├── _mediapipe_subprocess.py# WSL 下子进程跑 MediaPipe 的兜底(可选) +├── models/ +│ ├── face_landmarker.task # MediaPipe 模型(3.7MB,已复制) +│ └── face-parsing/ # SegFormer 权重(离线,已下载,见 OFFLINE_ASSETS.md) +│ ├── config.json +│ ├── preprocessor_config.json +│ └── model.safetensors +├── mesh/ +│ ├── face_ext.obj # 502 点扩展 mesh + UV + 三角面(渲染器读这个) +│ └── face.obj # 原始 468 点 mesh(参考/重生成用) +└── reference/ + ├── texture0.png # head3d 原 5 弧线贴图(核对 UV 用) + └── uv_template.png # UV 布局参考 +``` + +发际线类型贴图在仓库根目录 `hairline_texture/`(用户提供,9 张)。 + +### 2.1 移植后需要修改的集成点 + +1. **`face_landmarks.py` 的 `DEFAULT_MODEL_PATH`**:原逻辑是 `dirname(dirname(__file__))/models/...`(head3d 里模块在 `python/` 子目录)。现在模块在 `hairline/` 根,该路径会指向 `hair/models/`,而模型在 `hairline/models/`。**改为** `os.path.join(os.path.dirname(__file__), "models", "face_landmarker.task")`。 +2. **`face_parsing.py` 离线加载**:`C.HF_FACE_PARSER_MODEL` 当前是 HF 在线 id `"jonathandinu/face-parsing"`。内网/离线改为本地目录:把 `constants.py` 的 `HF_FACE_PARSER_MODEL` 指向 `hairline/models/face-parsing` 的绝对路径(`from_pretrained` 支持本地目录);或设 `HF_HUB_OFFLINE=1`。 +3. **相对导入**:模块用 `from . import constants`,已加 `hairline/__init__.py`,作为包导入即可(`from hairline.extract_hairline import run`)。 +4. **GPU**:`FaceParser(device="cuda")`,worker 有 GPU。 + +--- + +## 3. 算法管线(整体) + +``` +输入: 用户正面照 + gender + │ + ▼ +[A] head3d 管线(复用 hairline.extract_hairline 的步骤) + - MediaPipe 468 点(face_landmarker.task) + - SegFormer 人脸分割 → parse_map + - 17 锚点射线检测发际线 → 17 个 2D 点 → 平滑 + - 矢状-arc 提升 → 502 点(归一化 x,y,z) + │ 失败处理:无人脸→1001 + ▼ +[B] 投影到图像像素 + - 502 点的 (x,y) × (W,H) → 502 个 2D 图像坐标 + - 读 face_ext.obj:UV(502) + 扩展三角面(涉及顶点 ≥468 的 64 个三角形) + ▼ +[C] 逐张贴图渲染(新写的服务端渲染器,本方案核心) + for 每个该性别的发际线贴图 t: + - 对每个扩展三角形:src=UV→贴图像素, dst=投影 2D 坐标 → cv2 仿射 warp + - 累积成一张 RGBA 曲线层(贴图 alpha 控制曲线/透明) + - 把曲线层 alpha 合成到原照片上 → 预览图 + ▼ +[D] 输出 + results[] = N 个 {image(预览图), hairline_type(key), order=1..N} + worker 侧每张图以 base64 返回(见 §6) +``` + +--- + +## 4. 渲染器(新代码,本期重点)★ + +head3d 把贴图渲染到照片是**浏览器 Three.js** 做的(`/preview` ortho overlay),**没有服务端实现**。本期新写一个 **OpenCV 逐三角形仿射 warp** 渲染器,无需 OpenGL 离屏上下文,确定性好、部署简单。 + +### 4.1 原理 + +face_ext.obj 的 502 顶点里: +- `[0..467]` MediaPipe 点,其中 17 个 `MP_TOP_ANCHORS` 是发际线 ribbon 的**下边沿**; +- `[468..484]` 中间行、`[485..501]` 发际线行,是 ribbon 的中、上两行。 + +这 34 个新点 + 17 个锚点之间连成 64 个三角形(ribbon),它们的 UV 落在贴图**顶部条带**(V_raw≈0.67..0.94,正是发际线曲线所在)。所以只要把**这 64 个三角形**按 UV→图像坐标 warp,就能把贴图里的发际线曲线贴到照片的额头/发际线区域。 + +### 4.2 步骤 + +```python +# 伪代码 +def render_hairline_overlay(photo_bgr, points502_norm, ext_faces, uv502, texture_rgba): + H, W = photo_bgr.shape[:2] + # 502 点投影到图像像素 + img_xy = points502_norm[:, :2] * [W, H] # (502, 2) + TW, TH = texture_rgba.shape[1], texture_rgba.shape[0] # 512, 512 + + overlay = np.zeros((H, W, 4), np.float32) # 累积曲线层 RGBA + for (i, j, k) in ext_faces: # 仅扩展三角形(顶点含 ≥468) + dst = img_xy[[i, j, k]].astype(np.float32) # 图像坐标 + # UV → 贴图像素。注意 flipY:贴图 y = (1 - v_raw) * TH + src = np.array([[uv502[v][0]*TW, (1-uv502[v][1])*TH] for v in (i,j,k)], np.float32) + M = cv2.getAffineTransform(src, dst) + warped = cv2.warpAffine(texture_rgba, M, (W, H), flags=cv2.INTER_LINEAR, + borderMode=cv2.BORDER_CONSTANT, borderValue=(0,0,0,0)) + # 三角形掩码,避免覆盖整张 warp 结果 + tri_mask = np.zeros((H, W), np.uint8) + cv2.fillConvexPoly(tri_mask, dst.astype(np.int32), 255) + sel = tri_mask > 0 + overlay[sel] = warped[sel] # 逐三角形写入(相邻共享边,覆盖等价) + + # alpha 合成到原照片 + a = overlay[:, :, 3:4] / 255.0 + out = photo_bgr.astype(np.float32) + out = out * (1 - a) + overlay[:, :, :3][..., ::-1] * a # RGBA→BGR 注意通道序 + return out.astype(np.uint8) +``` + +### 4.3 注意点 + +- **通道序**:贴图是 RGBA,照片 OpenCV 是 BGR,合成时注意 R/B 调换。 +- **flipY**:face_ext.obj 的 UV 是 V_raw(V=1 对应贴图顶部),转贴图像素 y 要 `(1 - v)`,与 head3d Three.js `texture.flipY=true` 一致。 +- **只 warp 扩展三角形**:从 face_ext.obj 筛出顶点索引含 ≥468 的面(约 64 个)。不要 warp 整脸。 +- **抗锯齿/接缝**:逐三角形 `fillConvexPoly` 掩码可能在共享边留 1px 缝。可对 `tri_mask` 略膨胀,或最后对 overlay alpha 做轻微羽化。先跑通看效果再优化。 +- **裁剪到额头**:曲线层只在 ribbon 区域有内容(贴图其余透明),天然不会画到脸下半部。 + +--- + +## 5. 依赖 + +worker 已有(接口 1):`opencv-python`、`numpy`、`Pillow`、torch(CUDA)。接口 2 **新增**: + +``` +mediapipe>=0.10 # Tasks Vision FaceLandmarker(注意与接口1的 solutions API 可共存) +transformers>=4.40 # SegFormer 人脸分割 +# torch/torchvision 已由接口1引入(worker CUDA 版) +``` + +> ⚠️ **两套人脸分割模型**:接口 1 用 BiSeNet(`79999_iter.pth`),接口 2 用 head3d 的 SegFormer(`jonathandinu/face-parsing`)。两者并存,显存/内存够(worker 32G+GPU)。后续可评估是否统一为一个分割模型,本期先各用各的,**不强行合并**。 +> +> ⚠️ **MediaPipe API 差异**:接口 1 用 `mp.solutions.face_mesh`(468 点 + 虹膜 refine),接口 2 用 `mp.tasks.vision.FaceLandmarker`(读 `.task` 文件)。同一个 mediapipe 包都支持,但版本需兼容两者(建议先用一个版本把两接口都跑通)。 + +--- + +## 6. worker 集成(接口 2 handler) + +在 `app.py` 替换 `/api/v1/hair/grow` 的 Mock: + +``` +1. 解析图片(三选一)+ 读 gender(必填,male/female;非法→1004 或 1008 参数错误) +2. 校验(大小/解码/分辨率,同接口1) +3. 跑 hairline.extract_hairline 的步骤拿 502 点(无人脸→1001) +4. 按 gender 取贴图集合(启动时扫描 hairline_texture/ 建映射) +5. for 每张贴图: render_hairline_overlay → PNG +6. results[] = [{image_base64, hairline_type, order}], 逐张 base64 +7. return ok({"results": results}) +``` + +- **拆分架构**:worker 返回 `results[].image_base64`,**不落盘不拼 URL**。网关把每个 `image_base64` 落盘改写成 `image_url`(架构文档 §9 的映射表需支持**数组里的图片字段** `results[].image`)。 +- 模型单例:`FaceLandmarker` 和 `FaceParser` 在模块加载时初始化一次,避免每请求重建。face_ext.obj 的 UV/faces 也只解析一次缓存。 + +--- + +## 7. 离线资产(内网部署) + +接口 2 新增需要随项目带入内网的模型(已下载,登记到 `OFFLINE_ASSETS.md`): +- `hairline/models/face_landmarker.task`(MediaPipe,~3.7MB) +- `hairline/models/face-parsing/`(SegFormer:config + preprocessor + model.safetensors) + +> SegFormer 加载方式改本地路径后,内网无需联网(见 §2.1)。 + +--- + +## 8. 开发步骤与验证(agent 执行) + +| 阶段 | 内容 | 验证 | +|------|------|------| +| **M0 跑通管线** | 修好集成点(§2.1),用一张人像跑 `hairline.extract_hairline.run()` 得 502 点 JSON | 502 点、valid_hairline 有 true | +| **M1 解析 mesh** | 读 face_ext.obj 拿 UV + 扩展三角面(顶点≥468 的面),缓存 | 打印扩展面数(~64)、502 个 UV | +| **M2 渲染器** | 实现 `render_hairline_overlay`,对 1 张贴图渲染 | 输出预览图,**目视**:发际线曲线贴在额头正确位置、跟随脸 | +| **M3 全量 + 性别** | 扫描 `hairline_texture/` 建 gender→贴图映射,按性别渲染 N 张 | female 出 5 张、male 出 4 张,hairline_type 对 | +| **M4 接 app.py** | handler + gender 必填 + base64 返回 | curl 验证 results 数量/字段;无人脸→1001;缺 gender→报错 | +| **M5 网关映射** | 网关支持 `results[].image_base64`→`image_url`(网关任务书侧) | 端到端经网关返回 image_url,公网可访问 | + +**M2 是关键里程碑**:渲染器对齐效果好不好,决定整个接口可用性,先用几张测试人像目视确认贴合。 + +--- + +## 9. 风险与待办 + +1. **新贴图 UV 是否与 texture0 完全一致**:本方案假设 9 张贴图沿用 head3d 的顶部条带 UV 布局(已肉眼确认曲线在顶部)。M2 渲染若位置偏移,核对贴图内容所在的 V 区间与 `UV_MIDDLE_DV/UV_HAIRLINE_DV`。 +2. **接缝/锯齿**:逐三角形 warp 的共享边接缝,M2 跑通后按 §4.3 优化。 +3. **歪头/非正面**:head3d 矢状-arc 假设近正脸,大角度发际线贴合差。可复用接口 1 的 solvePnP 做前置姿态校验(可选)。 +4. **秃头/高发际线/刘海**:SegFormer 找不到头发时射线回退几何外推,曲线可能偏高;valid_hairline 标记可用于提示。 +5. **排序**:本期 order=1..N。后续排序需定义依据(脸型/额型匹配度)。 +6. **真正的生发(文生图)**:本期只出遮罩/预览。下一步把预览图/曲线作为 ControlNet/inpaint 输入接文生图模型,再替换 `image_url` 为真实生发图。 + +--- + +> **文档版本**: v1.0 | **创建日期**: 2026-06-14 | 算法来源: head3d(502 点 mesh + UV)| 运行位置: worker(GPU) +> **本期产出**: 发际线曲线叠加预览图(非最终生发图) diff --git a/docs/接口文档.md b/docs/接口文档.md index fbcd9d9..27b2dab 100644 --- a/docs/接口文档.md +++ b/docs/接口文档.md @@ -177,7 +177,9 @@ ## 接口 2:C 端生发接口 -**说明**:输入用户正面照,输出生发后的图片,以及推荐的发际线(可能多张),并按合适度排序。 +**说明**:输入用户正面照 + 性别,按性别对应的发际线类型,逐张把建议发际线渲染到照片上,输出多张方案。 + +> **当前阶段(第一步)**:`image_url` 返回的是「**原照片 + 发际线曲线叠加的预览图**」,尚未做真正的文生图生发;后续会替换为生发后图片。实现见 [`接口2-C端生发-技术实现方案.md`](接口2-C端生发-技术实现方案.md)。 **请求**:`POST /api/v1/hair/grow` @@ -187,19 +189,20 @@ | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| -| beauty_enabled | bool | 否 | 生发图是否带美颜效果,默认 false。提供该开关 | +| gender | string | **是** | 性别:`male` / `female`。决定使用的发际线贴图集合 | +| beauty_enabled | bool | 否 | 生发图是否带美颜效果,默认 false(当前阶段不生效) | ### 输出(data) -`results`:发际线方案数组(可能多张),每个元素: +`results`:发际线方案数组,**数量 = 该性别的发际线类型数**(`female` 5 个 / `male` 4 个)。每个元素: | 字段 | 类型 | 说明 | |------|------|------| -| image_url | string | 生发后图片 URL | -| hairline_type | string | 图片对应的发际线形(如:花瓣形、波浪形) | -| order | int | 排序序号(1 = 最优,2 次之 …) | +| image_url | string | 方案预览图 URL(当前 = 发际线叠加图) | +| hairline_type | string | 发际线类型 key:`ellipse`/`flower`/`heart`/`straight`/`wave`(female),`ellipse`/`m`/`straight`/`inverse_arc`(male) | +| order | int | 排序序号(当前阶段固定 `1..N`,按贴图顺序,暂不计算合适度) | -### 响应示例(当前 Mock 返回值) +### 响应示例 ```json { @@ -208,14 +211,14 @@ "request_id": "mock-request-id", "data": { "results": [ - { "image_url": "https://hair.xiangsilian.com/static/sample.jpg", "hairline_type": "花瓣形", "order": 1 }, - { "image_url": "https://hair.xiangsilian.com/static/sample.jpg", "hairline_type": "波浪形", "order": 2 } + { "image_url": "https://hair.xiangsilian.com/static/annotations/uuid1.png", "hairline_type": "ellipse", "order": 1 }, + { "image_url": "https://hair.xiangsilian.com/static/annotations/uuid2.png", "hairline_type": "flower", "order": 2 } ] } } ``` -> 识别失败时返回通用错误码(1001 / 1002 / 1003 等)。 +> 识别失败时返回通用错误码(1001 / 1002 / 1003 等)。`gender` 缺失或非法值返回参数错误(1008);本接口已改为必填入参,不再自动判别性别(1004 不再使用)。 --- diff --git a/hairline/__init__.py b/hairline/__init__.py new file mode 100644 index 0000000..f0a2232 --- /dev/null +++ b/hairline/__init__.py @@ -0,0 +1,7 @@ +"""接口 2(C 端生发)发际线渲染管线。 + +从 head3d 项目移植:MediaPipe 468 点 + SegFormer 人脸分割 + 17 锚点射线检测发际线 +→ 502 点 3D mesh(face_ext.obj)+ UV → 把发际线类型贴图渲染到照片对应位置。 + +模块来源见 docs/接口2-C端生发-技术实现方案.md。 +""" diff --git a/hairline/_index_map_data.py b/hairline/_index_map_data.py new file mode 100644 index 0000000..a9e23d6 --- /dev/null +++ b/hairline/_index_map_data.py @@ -0,0 +1,55 @@ +"""Auto-extracted indexMap[468] from the SDK's hardcode_data.h. + +Each entry: OBJ-vertex-index i -> MediaPipe canonical landmark index. +Do not edit by hand; regenerate from the C++ source. +""" + +INDEX_MAP_468 = [ + 127, 34, 139, 11, 0, 37, 232, 231, 120, 72, + 39, 128, 121, 47, 104, 69, 67, 175, 171, 148, + 118, 50, 101, 73, 40, 9, 151, 108, 48, 115, + 131, 194, 204, 211, 74, 185, 80, 42, 183, 92, + 186, 230, 229, 202, 212, 214, 83, 18, 17, 76, + 61, 146, 160, 29, 30, 56, 157, 173, 106, 135, + 192, 203, 165, 98, 21, 71, 68, 51, 45, 4, + 144, 24, 23, 77, 91, 205, 187, 201, 200, 182, + 90, 181, 85, 84, 206, 36, 140, 193, 189, 244, + 159, 158, 28, 247, 246, 161, 236, 3, 196, 54, + 168, 8, 117, 228, 31, 55, 97, 99, 126, 100, + 166, 79, 218, 155, 154, 26, 209, 49, 136, 150, + 217, 223, 52, 53, 134, 170, 43, 119, 226, 130, + 63, 238, 20, 242, 46, 70, 156, 78, 62, 96, + 143, 227, 123, 111, 44, 125, 19, 216, 153, 22, + 167, 208, 142, 57, 60, 35, 113, 27, 210, 225, + 137, 116, 41, 38, 129, 64, 240, 102, 207, 184, + 169, 149, 176, 105, 66, 122, 6, 147, 65, 107, + 89, 180, 93, 15, 86, 14, 87, 145, 88, 179, + 95, 138, 172, 215, 58, 219, 81, 195, 199, 82, + 163, 110, 234, 109, 235, 191, 222, 141, 221, 197, + 25, 7, 33, 220, 237, 245, 162, 188, 174, 2, + 241, 164, 12, 13, 198, 133, 112, 243, 239, 190, + 32, 178, 132, 177, 1, 213, 59, 94, 75, 224, + 233, 114, 124, 356, 389, 368, 302, 267, 452, 350, + 349, 303, 269, 357, 343, 277, 453, 333, 332, 297, + 152, 377, 347, 348, 330, 304, 270, 336, 337, 278, + 279, 360, 418, 262, 431, 408, 409, 310, 415, 407, + 410, 450, 422, 430, 434, 313, 314, 306, 307, 375, + 387, 388, 260, 286, 414, 398, 335, 406, 364, 367, + 416, 423, 358, 327, 251, 284, 298, 281, 5, 373, + 374, 253, 320, 321, 425, 427, 411, 421, 405, 404, + 315, 16, 426, 266, 400, 369, 322, 391, 417, 465, + 464, 386, 257, 258, 466, 456, 399, 419, 285, 346, + 340, 261, 413, 441, 460, 328, 355, 371, 329, 392, + 439, 438, 382, 341, 256, 429, 420, 394, 379, 437, + 443, 444, 283, 275, 440, 363, 338, 273, 451, 446, + 342, 467, 293, 334, 282, 458, 461, 462, 276, 353, + 383, 308, 324, 325, 300, 372, 345, 447, 352, 274, + 248, 436, 381, 252, 393, 428, 287, 250, 384, 265, + 259, 424, 292, 366, 271, 294, 455, 272, 432, 395, + 299, 351, 280, 319, 295, 296, 403, 323, 454, 316, + 380, 318, 402, 365, 435, 397, 344, 311, 291, 396, + 268, 445, 254, 339, 449, 264, 10, 442, 370, 263, + 255, 359, 412, 301, 378, 326, 457, 362, 459, 463, + 354, 401, 361, 309, 376, 433, 289, 305, 448, 290, + 288, 249, 103, 385, 331, 317, 312, 390, +] diff --git a/hairline/_mediapipe_subprocess.py b/hairline/_mediapipe_subprocess.py new file mode 100644 index 0000000..0e952cc --- /dev/null +++ b/hairline/_mediapipe_subprocess.py @@ -0,0 +1,67 @@ +"""Standalone MediaPipe FaceLandmarker runner used by web_service.py. + +Running MediaPipe Tasks in the same process as the Flask dev server can +segfault under WSL (D3D12 EGL backend). Spawning a fresh subprocess per +request keeps the web server alive and lets us inject WSL-friendly env +vars before any mediapipe import. + +Usage: + python -m python._mediapipe_subprocess +""" +from __future__ import annotations + +import os +import sys + +os.environ.setdefault("LIBGL_ALWAYS_SOFTWARE", "1") +os.environ.setdefault("MESA_LOADER_DRIVER_OVERRIDE", "llvmpipe") +os.environ.setdefault("GALLIUM_DRIVER", "llvmpipe") +os.environ.setdefault("MEDIAPIPE_DISABLE_GPU", "1") +os.environ.setdefault("EGL_PLATFORM", "surfaceless") + +import numpy as np # noqa: E402 + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) +PROJECT_DIR = os.path.dirname(THIS_DIR) +if PROJECT_DIR not in sys.path: + sys.path.insert(0, PROJECT_DIR) + +from python.face_landmarks import FaceLandmarker # noqa: E402 + + +def main() -> int: + if len(sys.argv) != 3: + print( + "usage: python -m python._mediapipe_subprocess ", + file=sys.stderr, + ) + return 2 + + image_path, output_path = sys.argv[1], sys.argv[2] + + import cv2 + + bgr = cv2.imread(image_path) + if bgr is None: + print(f"could not read image: {image_path}", file=sys.stderr) + return 3 + + rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) + rgb = np.ascontiguousarray(rgb, dtype=np.uint8) + + landmarker = FaceLandmarker(static_image_mode=True) + try: + landmarks = landmarker.detect(rgb) + finally: + landmarker.close() + + if landmarks is None: + print("no face detected", file=sys.stderr) + return 4 + + np.save(output_path, landmarks.astype(np.float32)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/hairline/constants.py b/hairline/constants.py new file mode 100644 index 0000000..ecafb05 --- /dev/null +++ b/hairline/constants.py @@ -0,0 +1,165 @@ +"""Shared constants for the hairline-extension pipeline. + +These define the topology of the extended mesh and must stay in sync with +the C++ side (see sdk/ExtensionConstants.h). If you change anything here, +regenerate face_ext.obj and update the C++ header. +""" +from __future__ import annotations + +# Number of MediaPipe FaceMesh landmarks (no iris refinement). +N_MP = 468 + +# Anchors along the upper boundary of the MediaPipe face mesh, +# ordered left-to-right when viewing the face frontally. +# Each anchor will get a paired hairline sample directly "above" it. +# +# Verify visually with scripts/show_anchors.py before locking these in. +MP_TOP_ANCHORS: list[int] = [ + 127, 234, 162, 21, 54, 103, 67, 109, 10, + 338, 297, 332, 284, 251, 389, 356, 454, +] +N_ANCHORS = len(MP_TOP_ANCHORS) # 17 + +# Vertex ID layout in the extended array of length 468 + 2*N_ANCHORS. +# [0 .. 468) : MediaPipe canonical landmarks +# [468 .. 468+N) : middle row (between MP boundary and hairline) +# [468+N .. 468+2N) : hairline row +N_EXT = 2 * N_ANCHORS # 34 +N_TOTAL = N_MP + N_EXT # 502 + +MIDDLE_START = N_MP # 468 +HAIRLINE_START = N_MP + N_ANCHORS # 485 + +# Saggital head-curvature radius (in MediaPipe normalized-Y units), +# expressed as a fraction of face height. The head's mid-line cross +# section is treated locally as a circular arc; for a hairline / middle +# vertex located dy=(y_hair - y_anchor) above an MP top anchor (dy < 0 +# since hairline y < anchor y) we compute its Z by +# +# z_hair = z_anchor + dy² / (2 R), R = HEAD_ARC_RADIUS_FRAC × face_h +# +# This always pushes the added vertex BACKWARD (toward +z in MP / face.obj +# convention, i.e. toward the back of the head), matching the actual +# anatomy. See README for the derivation. +# +# Smaller fraction = more pronounced backward bulge. 0.30 produces a +# moderate offset (~0.024 in normalized z for a 0.08-y hairline lift on +# a typical face). +HEAD_ARC_RADIUS_FRAC = 0.30 + + +# Extra lift applied to the detected hairline along the face-up direction, +# expressed as a fraction of the MP face height. The 2D hairline detector +# stops at the hair-skin boundary (start of the visible hair); the mesh +# ribbon's top row should sit at the crown of the head instead, so the +# texture-overlay band can cover the whole forehead → crown region. +# +# 0.06 ≈ moves the hairline row up by 6% of face height, which on the +# reference photos lands the top row just above the visible hairline and +# below the crown — empirically tuned with the /preview slider and locked +# in as the project default. Bump to 0.10..0.15 for taller foreheads / +# higher crowns; drop to 0.03 to keep the ribbon hugging the hair-skin +# boundary. +HAIRLINE_CROWN_LIFT_FRAC = 0.06 + + +# Pure-geometry hairline offset for the /preview 502-point pipeline. +# +# When placing the hairline row WITHOUT hair detection (works for bald / +# with-hair / hat — all head types), each anchor is offset upward along +# face-up by GEOMETRIC_HAIRLINE_OFFSET_FRAC × face_h in normalised +# image space. The sagittal-arc model then derives Z. +# +# 0.25 × face_h ≈ 0.12 normalised on a typical face (face_h ≈ 0.48), +# giving dz ≈ 0.05 — matches the real hairline distance observed on +# reference photos where hair detection succeeds. +GEOMETRIC_HAIRLINE_OFFSET_FRAC = 0.25 + + +# UV layout for the 34 forehead-extension vertices. +# +# The texture (imgs/texture0.png, 512×512) is laid out with the original +# MediaPipe face skin in V_raw ≈ 0.00..0.77 (image y ≈ 117..511) and a +# horizontal stack of 5 hairline-design arcs at the TOP of the image +# (image y ≈ 30..170, i.e. V_raw ≈ 0.67..0.94). Those 5 arcs are the +# content that the extension strip is supposed to display: hairline row +# samples the topmost arc (blue), middle row samples the bottom arc +# (orange), and the 3 arcs in between fall out automatically because the +# ribbon triangle interpolates V linearly between the two rows. +# +# V conventions +# ------------- +# uv_template.py / Three.js (with texture.flipY=true) treat V_raw=1 as +# the TOP of the image (image y=0) and V_raw=0 as the BOTTOM. +# +# U conventions — IMPORTANT +# ------------------------- +# The 17 MP_TOP_ANCHORS in face.obj have NON-uniform u (≈ 0.00 at the +# temples, ≈ 0.50 at the forehead center, ≈ 1.00 at the other temple). +# Each ribbon triangle (anchor[i] → middle[i] → anchor[i+1] etc.) is a +# vertical column in UV space ONLY when the middle/hairline vertex +# inherits its U from the corresponding anchor. If we used a uniform +# 0.05..0.95 U for the strip the columns would slant relative to the +# anchor U values, warping the texture's 5 horizontal arcs into +# zig-zags. So `extension_uv_for` takes `anchor_u` and copies it. +UV_MIDDLE_DV = 0.110 # middle 行 V_raw 相对该列 anchor V_raw 上移这么多 +UV_HAIRLINE_DV = 0.220 # hairline 行 V_raw 相对该列 anchor V_raw 上移这么多 +# 为什么是"相对 anchor 平行偏移"而不是固定常数: +# +# face.obj 中 17 个 MP_TOP_ANCHORS 的 V_raw 是**非均匀弧形** (额头中央 MP 10 +# = 0.7724, 太阳穴 MP 127 = 0.4668, 横跨 0.30 V 单位)。 如果 middle/hairline +# 用固定常数 V_raw (例如 0.82 / 0.998), 那每个 ribbon quad 的 V 跨度 +# (= middle.V − anchor[i].V) 在 17 列之间差异巨大 (中央列 0.05, 两端列 0.35, +# 差了 7 倍)。 贴图最底部的弧线 (V_raw ≈ 0.76) 正好落在 V 跨度大的列上 → +# 被拉伸成粗大色块, 而顶部弧线 (V_raw ≈ 0.93) 落在 V 跨度小的列上 → 被压 +# 缩成细线。 这就是"最下面那条线特别粗、上面 4 根都细"的根因。 +# +# 把 middle/hairline 的 V 也设成"anchor V + 固定 Δ", 每列的 V 跨度变成恒定 +# 的 Δm / (Δh − Δm), ribbon 在贴图上是上下都跟随 anchor 弧度的弯月形带, +# 贴图 5 条弧线在 mesh 上粗细均匀。 +# +# 硬约束: +# 1. Δm > 0 且 Δm < Δh (顺序保持 anchor < middle < hairline, 防 V 反向) +# 2. anchor.V_max + Δh ≤ 1.0 (即 Δh ≤ 1 − 0.7724 = 0.2276) +# 否则中央列 hairline V 溢出, 采到贴图边缘的抗锯齿像素。 +# 当前 Δh = 0.220 留 ≈ 0.008 V 单位 buffer; Δm = Δh / 2 让上下两段等宽。 + + +def extension_uv_for(row: int, anchor_u: float, anchor_v: float) -> tuple[float, float]: + """Return (u, v_raw) UV for an extension vertex. + + row: 0 = middle, 1 = hairline. + anchor_u: U of the corresponding MP anchor (copy verbatim → ribbon column + is vertical in UV space). + anchor_v: V_raw of the corresponding MP anchor (we add a constant Δ to + it → ribbon row stays parallel to anchor row in UV space, so + each quad has the same V span and texture arcs render at the + same thickness across all 17 columns). + """ + dv = UV_MIDDLE_DV if row == 0 else UV_HAIRLINE_DV + return (anchor_u, anchor_v + dv) + + +# Face-parsing class indices for the jonathandinu/face-parsing +# SegFormer model (matches CelebAMask-HQ labels): +PARSE_BG = 0 +PARSE_SKIN = 1 +PARSE_NOSE = 2 +PARSE_EYE_G = 3 +PARSE_L_EYE = 4 +PARSE_R_EYE = 5 +PARSE_L_BROW = 6 +PARSE_R_BROW = 7 +PARSE_L_EAR = 8 +PARSE_R_EAR = 9 +PARSE_MOUTH = 10 +PARSE_U_LIP = 11 +PARSE_L_LIP = 12 +PARSE_HAIR = 13 +PARSE_HAT = 14 +PARSE_EAR_R = 15 +PARSE_NECK_L = 16 +PARSE_NECK = 17 +PARSE_CLOTH = 18 + +HF_FACE_PARSER_MODEL = "jonathandinu/face-parsing" diff --git a/hairline/extract_hairline.py b/hairline/extract_hairline.py new file mode 100644 index 0000000..6f3f1cd --- /dev/null +++ b/hairline/extract_hairline.py @@ -0,0 +1,115 @@ +"""Main CLI: image -> JSON of 502 3D points consumable by the SDK. + +Pipeline: + 1. MediaPipe FaceMesh -> 468 normalized landmarks + 2. Face parsing (HF SegFormer) -> per-pixel class map + 3. Hairline curve detection + per-anchor ray casting -> 17 hairline 2D points + 4. Lift 2D hairline points to 3D using anchor Z + curvature offset + 5. Interpolate 17 middle-row 3D points + 6. Concatenate into (502, 3) and emit JSON + +Output JSON schema: + { + "image": {"width": W, "height": H, "path": "..."}, + "n_total": 502, + "n_mp": 468, + "n_extension": 34, + "layout": ["mp[0..468)", "middle[468..485)", "hairline[485..502)"], + "points": [[x_norm, y_norm, z_relative], ...] # length 502 + "valid_hairline": [true/false, ...] # length 17 + } + +Usage: + py -3 python/extract_hairline.py path/to/image.jpg + py -3 python/extract_hairline.py path/to/image.jpg --out data/out.json +""" +from __future__ import annotations +import argparse +import json +import os +import sys +import time + +import numpy as np + +if __package__ is None or __package__ == "": + sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + from python import constants as C + from python.face_landmarks import FaceLandmarker + from python.face_parsing import FaceParser + from python.hairline_2d import sample_hairline, smooth_hairline + from python.lift_3d import lift_hairline_to_3d, build_middle_row, assemble_full +else: + from . import constants as C + from .face_landmarks import FaceLandmarker + from .face_parsing import FaceParser + from .hairline_2d import sample_hairline, smooth_hairline + from .lift_3d import lift_hairline_to_3d, build_middle_row, assemble_full + + +def run(image_path: str, out_path: str | None = None, device: str | None = None) -> dict: + import cv2 + bgr = cv2.imread(image_path) + if bgr is None: + raise FileNotFoundError(f"could not read image: {image_path}") + rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) + H, W = rgb.shape[:2] + + t0 = time.perf_counter() + lmk = FaceLandmarker(static_image_mode=True) + landmarks = lmk.detect(rgb) + lmk.close() + if landmarks is None: + raise RuntimeError("no face detected") + t1 = time.perf_counter() + print(f" [time] mediapipe: {(t1 - t0)*1000:.0f} ms") + + parser = FaceParser(device=device) + parse_map = parser.parse(rgb) + t2 = time.perf_counter() + print(f" [time] parsing: {(t2 - t1)*1000:.0f} ms") + + hairline_2d, valid = sample_hairline(landmarks, parse_map) + hairline_2d = smooth_hairline(hairline_2d, valid) + hairline_3d = lift_hairline_to_3d(landmarks, hairline_2d) + middle_3d = build_middle_row(landmarks, hairline_3d) + points_full = assemble_full(landmarks, middle_3d, hairline_3d) + t3 = time.perf_counter() + print(f" [time] hairline: {(t3 - t2)*1000:.0f} ms") + + record = { + "image": {"width": int(W), "height": int(H), "path": image_path}, + "n_total": C.N_TOTAL, + "n_mp": C.N_MP, + "n_extension": C.N_EXT, + "layout": [ + f"mp[0..{C.N_MP})", + f"middle[{C.MIDDLE_START}..{C.HAIRLINE_START})", + f"hairline[{C.HAIRLINE_START}..{C.N_TOTAL})", + ], + "points": points_full.tolist(), + "valid_hairline": valid.tolist(), + } + + if out_path is None: + base = os.path.splitext(os.path.basename(image_path))[0] + out_path = os.path.join("data", base + ".json") + + os.makedirs(os.path.dirname(out_path) or ".", exist_ok=True) + with open(out_path, "w", encoding="utf-8") as f: + json.dump(record, f, ensure_ascii=False, indent=2) + print(f" wrote {out_path}") + return record + + +def main() -> None: + ap = argparse.ArgumentParser(description="Extract MediaPipe + hairline points from one image.") + ap.add_argument("image", help="path to input image (jpg/png)") + ap.add_argument("--out", default=None, help="output JSON path") + ap.add_argument("--device", default=None, help="torch device (cpu/cuda); auto if omitted") + args = ap.parse_args() + run(args.image, args.out, args.device) + + +if __name__ == "__main__": + main() diff --git a/hairline/face_landmarks.py b/hairline/face_landmarks.py new file mode 100644 index 0000000..77fe3b7 --- /dev/null +++ b/hairline/face_landmarks.py @@ -0,0 +1,103 @@ +"""MediaPipe FaceMesh wrappers returning 468 3D landmarks in [0,1] x/y space. + +`FaceLandmarker` uses the modern mediapipe.tasks.vision API and requires +models/face_landmarker.task. + +`SolutionsFaceLandmarker` uses the older mediapipe.solutions.face_mesh API. +It is useful as a CPU fallback in WSL environments where the Tasks API may +segfault while initializing EGL/OpenGL. +""" +from __future__ import annotations +import os +import numpy as np + +DEFAULT_MODEL_PATH = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "models", "face_landmarker.task", +) + + +class FaceLandmarker: + def __init__(self, static_image_mode: bool = True, model_path: str | None = None): + import mediapipe as mp + from mediapipe.tasks import python as mp_python + from mediapipe.tasks.python import vision + + path = model_path or DEFAULT_MODEL_PATH + if not os.path.isfile(path): + raise FileNotFoundError( + f"face_landmarker.task not found at {path}. " + "Download it from " + "https://storage.googleapis.com/mediapipe-models/face_landmarker/" + "face_landmarker/float16/1/face_landmarker.task" + ) + + running_mode = vision.RunningMode.IMAGE if static_image_mode else vision.RunningMode.VIDEO + options = vision.FaceLandmarkerOptions( + base_options=mp_python.BaseOptions(model_asset_path=path), + running_mode=running_mode, + num_faces=1, + output_face_blendshapes=False, + output_facial_transformation_matrixes=False, + ) + self._detector = vision.FaceLandmarker.create_from_options(options) + self._mp = mp + + def detect(self, image_rgb: np.ndarray) -> np.ndarray | None: + """Returns (468, 3) float32 of normalized x, y and relative z, or None. + + The task model produces 478 landmarks (468 face + 10 iris); we return + only the first 468 to match the canonical FaceMesh topology used by + the SDK's OBJ file. + """ + mp_image = self._mp.Image(image_format=self._mp.ImageFormat.SRGB, data=image_rgb) + result = self._detector.detect(mp_image) + if not result.face_landmarks: + return None + lm = result.face_landmarks[0][:468] + arr = np.array([[p.x, p.y, p.z] for p in lm], dtype=np.float32) + return arr + + def close(self): + try: + self._detector.close() + except Exception: + pass + + +class SolutionsFaceLandmarker: + """CPU-oriented fallback using mediapipe.solutions.face_mesh.""" + + def __init__(self, static_image_mode: bool = True): + import mediapipe as mp + + try: + face_mesh_module = mp.solutions.face_mesh + except AttributeError as exc: + raise RuntimeError( + "当前 mediapipe 包不包含 mediapipe.solutions.face_mesh。" + "请使用 web_service.py 的默认 parsing backend,或安装包含 solutions API 的 mediapipe 版本。" + ) from exc + + self._face_mesh = face_mesh_module.FaceMesh( + static_image_mode=static_image_mode, + max_num_faces=1, + refine_landmarks=False, + min_detection_confidence=0.5, + ) + + def detect(self, image_rgb: np.ndarray) -> np.ndarray | None: + """Returns (468, 3) float32 of normalized x, y and relative z, or None.""" + image_rgb.flags.writeable = False + result = self._face_mesh.process(image_rgb) + image_rgb.flags.writeable = True + if not result.multi_face_landmarks: + return None + lm = result.multi_face_landmarks[0].landmark[:468] + return np.array([[p.x, p.y, p.z] for p in lm], dtype=np.float32) + + def close(self): + try: + self._face_mesh.close() + except Exception: + pass diff --git a/hairline/face_parsing.py b/hairline/face_parsing.py new file mode 100644 index 0000000..e20ce4f --- /dev/null +++ b/hairline/face_parsing.py @@ -0,0 +1,42 @@ +"""Face parsing via HuggingFace SegFormer (jonathandinu/face-parsing). + +First call downloads ~150 MB of weights into the HF cache. +""" +from __future__ import annotations +import numpy as np +from typing import TYPE_CHECKING + +from . import constants as C + +if TYPE_CHECKING: # avoid hard import at module load + pass + + +class FaceParser: + """Wraps a SegFormer face-parsing model and returns a (H, W) int label map.""" + + def __init__(self, device: str | None = None): + import torch + from transformers import SegformerImageProcessor, SegformerForSemanticSegmentation + + self.device = device or ("cuda" if torch.cuda.is_available() else "cpu") + self.processor = SegformerImageProcessor.from_pretrained(C.HF_FACE_PARSER_MODEL) + self.model = SegformerForSemanticSegmentation.from_pretrained(C.HF_FACE_PARSER_MODEL) + self.model.to(self.device).eval() + self._torch = torch + + def parse(self, image_rgb: np.ndarray) -> np.ndarray: + """image_rgb: (H, W, 3) uint8. Returns (H, W) int64 of class indices.""" + from PIL import Image + + H, W = image_rgb.shape[:2] + pil = Image.fromarray(image_rgb) + inputs = self.processor(images=pil, return_tensors="pt").to(self.device) + with self._torch.no_grad(): + logits = self.model(**inputs).logits # (1, C, h, w) + # Upsample to original resolution + up = self._torch.nn.functional.interpolate( + logits, size=(H, W), mode="bilinear", align_corners=False + ) + labels = up.argmax(dim=1).squeeze(0).to("cpu").numpy().astype(np.int32) + return labels diff --git a/hairline/hairline_2d.py b/hairline/hairline_2d.py new file mode 100644 index 0000000..758e076 --- /dev/null +++ b/hairline/hairline_2d.py @@ -0,0 +1,1029 @@ +"""2D hairline detection from a face-parsing label map. + +Given the parser output, find the boundary curve between hair-above and +skin-below in the upper face region, then sample one point per anchor +along the face's local "up" direction. + +This module also exposes several alternative strategies (see +``sample_hairline_*`` functions) that the Web service runs side-by-side +for visual comparison. +""" +from __future__ import annotations +from typing import Callable +import numpy as np + +from . import constants as C + + +def face_up_vector(landmarks_norm: np.ndarray) -> np.ndarray: + """Return a unit 2D vector pointing "up" in image space. + + landmarks_norm: (468, 3) MediaPipe output (normalized x,y in [0,1]). + Uses chin (152) → forehead-top (10). + """ + chin = landmarks_norm[152, :2] + top = landmarks_norm[10, :2] + v = top - chin # in normalized image space + n = np.linalg.norm(v) + 1e-9 + return v / n + + +def build_hair_mask(parse_map: np.ndarray) -> np.ndarray: + """Boolean (H, W) mask of pixels strictly classified as hair (or hat).""" + return np.isin(parse_map, [C.PARSE_HAIR, C.PARSE_HAT]) + + +def build_skin_mask(parse_map: np.ndarray) -> np.ndarray: + """Boolean (H, W) mask of pixels classified as facial skin / ears / brows / nose / lips. + + Used to validate that a ray actually travels through the face before + hitting hair — guards against the case where the ray exits laterally + into background (e.g. from a temple anchor next to white background) + and would otherwise stop at the first non-skin pixel. + """ + face_classes = [ + C.PARSE_SKIN, C.PARSE_NOSE, C.PARSE_L_BROW, C.PARSE_R_BROW, + C.PARSE_L_EYE, C.PARSE_R_EYE, C.PARSE_EYE_G, + C.PARSE_L_EAR, C.PARSE_R_EAR, C.PARSE_EAR_R, + C.PARSE_MOUTH, C.PARSE_U_LIP, C.PARSE_L_LIP, + ] + return np.isin(parse_map, face_classes) + + +def ray_first_hair_hit( + origin_xy: np.ndarray, + direction_xy: np.ndarray, + hair_mask: np.ndarray, + max_steps: int = 800, + step_px: float = 1.0, +) -> np.ndarray | None: + """March a ray until it hits a hair pixel. Returns float (x, y) or None. + + Unlike a generic boundary tracer, we explicitly target the HAIR class so + a ray that drifts into background while traversing a temple anchor will + continue searching rather than stopping at the face/background edge. + """ + H, W = hair_mask.shape + pos = origin_xy.astype(np.float64).copy() + for _ in range(max_steps): + pos += direction_xy * step_px + ix, iy = int(round(pos[0])), int(round(pos[1])) + if ix < 0 or iy < 0 or ix >= W or iy >= H: + return None + if hair_mask[iy, ix]: + return pos.copy() + return None + + +def sample_hairline( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + fallback_extrapolation: float = 0.18, +) -> tuple[np.ndarray, np.ndarray]: + """Find one hairline point per MP_TOP_ANCHORS, in normalized [0,1] image space. + + Returns: + hairline_norm: (N_ANCHORS, 2) float — hairline points (x_norm, y_norm) + valid_mask: (N_ANCHORS,) bool — True where a hair-pixel was hit + + Algorithm: + For each anchor, march a ray along the face's up-vector and return the + first hair-classified pixel encountered. If the ray exits the image + without ever finding hair (bald, hat, or hairline outside the frame), + fall back to extrapolating along the up-vector by `fallback_extrapolation`. + + For lateral anchors (temples, ears) the ray may leave the face into + background skin-less area before encountering hair on top of the + head — that is OK because we only stop on hair, not background. + """ + H, W = parse_map.shape + hair_mask = build_hair_mask(parse_map) + + up_norm = face_up_vector(landmarks_norm) + up_px = up_norm * np.array([W, H], dtype=np.float64) + up_px = up_px / (np.linalg.norm(up_px) + 1e-9) + + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + anchor_px = anchor_norm * np.array([W, H], dtype=np.float64) + hit_px = ray_first_hair_hit(anchor_px, up_px, hair_mask) + if hit_px is not None: + hairline[i] = (hit_px / np.array([W, H])).astype(np.float32) + valid[i] = True + else: + hairline[i] = (anchor_norm + up_norm * fallback_extrapolation).astype(np.float32) + valid[i] = False + return hairline, valid + + +# Backwards-compat alias for callers from the previous API. +def build_hairline_mask(parse_map: np.ndarray) -> np.ndarray: + return build_hair_mask(parse_map) + + +def smooth_hairline( + hairline_norm: np.ndarray, + valid: np.ndarray, + iterations: int = 2, +) -> np.ndarray: + """Light smoothing along the curve to absorb segmentation jitter. + + Uses a 1-2-1 binomial filter over neighbors with the same validity. + Note: this also rounds off real corners. For data with sharp corners + (e.g. M-shaped hairlines), use :func:`smooth_hairline_corner_aware` instead. + """ + out = hairline_norm.copy() + n = len(out) + for _ in range(iterations): + new = out.copy() + for i in range(1, n - 1): + if not valid[i]: + continue + new[i] = 0.25 * out[i - 1] + 0.5 * out[i] + 0.25 * out[i + 1] + out = new + return out + + +def smooth_hairline_corner_aware( + hairline_norm: np.ndarray, + valid: np.ndarray, + iterations: int = 2, + corner_cos_threshold: float = 0.6, +) -> np.ndarray: + """1-2-1 smoothing, but skip points that look like corners. + + A "corner" is detected by the cosine of the angle between (P[i] - P[i-1]) + and (P[i+1] - P[i]): smaller cosine = sharper bend. If + ``cos(angle) < corner_cos_threshold`` (i.e. bend > ~53°), point i keeps + its raw position; otherwise the binomial filter is applied. + + This preserves the user's expected M-shape / trapezoidal hairline whose + "shoulders" are sharp corners. + """ + out = hairline_norm.copy() + n = len(out) + for _ in range(iterations): + new = out.copy() + for i in range(1, n - 1): + if not valid[i]: + continue + v1 = out[i] - out[i - 1] + v2 = out[i + 1] - out[i] + n1 = float(np.linalg.norm(v1)) + n2 = float(np.linalg.norm(v2)) + if n1 < 1e-9 or n2 < 1e-9: + new[i] = 0.25 * out[i - 1] + 0.5 * out[i] + 0.25 * out[i + 1] + continue + cos_a = float(np.dot(v1, v2)) / (n1 * n2) + if cos_a >= corner_cos_threshold: + # smooth: not a corner + new[i] = 0.25 * out[i - 1] + 0.5 * out[i] + 0.25 * out[i + 1] + # else: keep raw (preserve corner) + out = new + return out + + +# --------------------------------------------------------------------------- +# Alternative hairline sampling strategies. +# +# All functions share the signature ``(landmarks_norm, parse_map) -> (hairline, +# valid)`` so the caller can switch strategies uniformly. ``landmarks_norm`` +# may be ``None`` for parsing-only strategies (e.g. ``sample_hairline_top_arc``). +# --------------------------------------------------------------------------- + + +def head_top_target(landmarks_norm: np.ndarray, scale: float = 0.6) -> np.ndarray: + """Return a 2D point above the forehead used as a ray convergence target. + + The point is placed `scale * face_height` above the forehead-top landmark + (10), measured along the chin->forehead axis. ``scale = 0.6`` roughly + matches the human "crown" position relative to the chin->forehead line. + """ + chin = landmarks_norm[152, :2] + top = landmarks_norm[10, :2] + face_height = float(np.linalg.norm(top - chin)) + 1e-9 + face_up_unit = (top - chin) / face_height + return top + face_up_unit * face_height * scale + + +def build_face_adjacent_hair_mask( + parse_map: np.ndarray, + dilate_radius: int | None = None, +) -> np.ndarray: + """Hair pixels that lie within ``dilate_radius`` px of any face-skin pixel. + + Used to filter out background blobs that the parser mis-classified as + hair (chairs, dark walls, etc.) which would otherwise stop a ray prematurely. + """ + import cv2 + + hair = np.isin(parse_map, [C.PARSE_HAIR, C.PARSE_HAT]).astype(np.uint8) + face = build_skin_mask(parse_map).astype(np.uint8) + + if dilate_radius is None: + face_area = int(face.sum()) + dilate_radius = max(6, int(np.sqrt(max(face_area, 1)) * 0.05)) + + k = 2 * dilate_radius + 1 + kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (k, k)) + face_dil = cv2.dilate(face, kernel) + return (hair > 0) & (face_dil > 0) + + +def ray_first_mask_hit( + origin_xy: np.ndarray, + direction_xy: np.ndarray, + mask: np.ndarray, + max_steps: int = 1500, + step_px: float = 1.0, +) -> np.ndarray | None: + """Generic version of :func:`ray_first_hair_hit` that targets any boolean mask.""" + H, W = mask.shape + pos = origin_xy.astype(np.float64).copy() + for _ in range(max_steps): + pos += direction_xy * step_px + ix, iy = int(round(pos[0])), int(round(pos[1])) + if ix < 0 or iy < 0 or ix >= W or iy >= H: + return None + if mask[iy, ix]: + return pos.copy() + return None + + +def ray_first_dense_hit( + origin_xy: np.ndarray, + direction_xy: np.ndarray, + mask: np.ndarray, + run_length: int, + max_steps: int = 2000, +) -> np.ndarray | None: + """Density-based stopping: stop only after `run_length` consecutive hit pixels. + + Returns the position of the FIRST pixel of the qualifying run (i.e., the + edge where the dense region begins). This filters out single-pixel + classification noise and isolated wisps. + + The ray is allowed to start outside the image and walk in until it enters + the image bounds (used by the "from-above" strategies). Once inside, if the + ray exits the image again, the search stops. + """ + H, W = mask.shape + pos = np.asarray(origin_xy, dtype=np.float64).copy() + direction = np.asarray(direction_xy, dtype=np.float64) + consecutive = 0 + run_start: np.ndarray | None = None + entered_image = False + + for _ in range(max_steps): + pos += direction + ix, iy = int(round(pos[0])), int(round(pos[1])) + in_image = (0 <= ix < W) and (0 <= iy < H) + if not in_image: + if entered_image: + return None + continue + entered_image = True + if mask[iy, ix]: + if consecutive == 0: + run_start = pos.copy() + consecutive += 1 + if consecutive >= run_length: + return run_start + else: + consecutive = 0 + run_start = None + return None + + +def _face_height_px(landmarks_norm: np.ndarray, W: int, H: int) -> float: + chin = landmarks_norm[152, :2] * np.array([W, H], dtype=np.float64) + top = landmarks_norm[10, :2] * np.array([W, H], dtype=np.float64) + return float(np.linalg.norm(top - chin)) + + +def density_run_length(landmarks_norm: np.ndarray, W: int, H: int, ratio: float = 0.06) -> int: + """Adaptive density threshold proportional to face size. + + Default ratio = 0.06 of the chin-to-forehead distance: for a 200 px face + height that gives a 12-pixel run requirement; for 400 px → 24 pixels. + """ + fh = _face_height_px(landmarks_norm, W, H) + return max(6, int(round(fh * ratio))) + + +def _ray_sample_with_direction( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + mask: np.ndarray, + direction_factory: Callable[[np.ndarray, np.ndarray, int, int], np.ndarray], + fallback_extrapolation: float = 0.18, +) -> tuple[np.ndarray, np.ndarray]: + """Common ray-marching loop. ``direction_factory`` returns a unit pixel-space + direction for a given anchor (passed `(landmarks, anchor_px, W, H)`).""" + H, W = parse_map.shape + up_norm_fallback = face_up_vector(landmarks_norm) + + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + anchor_px = anchor_norm * np.array([W, H], dtype=np.float64) + direction_px = direction_factory(landmarks_norm, anchor_px, W, H) + hit_px = ray_first_mask_hit(anchor_px, direction_px, mask) + if hit_px is not None: + hairline[i] = (hit_px / np.array([W, H])).astype(np.float32) + valid[i] = True + else: + hairline[i] = (anchor_norm + up_norm_fallback * fallback_extrapolation).astype(np.float32) + valid[i] = False + return hairline, valid + + +def _direction_face_up(landmarks_norm, anchor_px, W, H) -> np.ndarray: + up_norm = face_up_vector(landmarks_norm) + up_px = up_norm * np.array([W, H], dtype=np.float64) + return up_px / (np.linalg.norm(up_px) + 1e-9) + + +def _direction_converging(landmarks_norm, anchor_px, W, H, scale: float = 0.6) -> np.ndarray: + target_norm = head_top_target(landmarks_norm, scale=scale) + target_px = target_norm * np.array([W, H], dtype=np.float64) + d = target_px - anchor_px + return d / (np.linalg.norm(d) + 1e-9) + + +def sample_hairline_baseline(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """策略 1: 当前算法 - 沿 face-up 直上, 命中首个 hair/hat 像素。""" + mask = build_hair_mask(parse_map) + return _ray_sample_with_direction(landmarks_norm, parse_map, mask, _direction_face_up) + + +def sample_hairline_adjacent(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """策略 2: baseline + hair 必须邻接 face skin, 过滤背景误分。""" + mask = build_face_adjacent_hair_mask(parse_map) + return _ray_sample_with_direction(landmarks_norm, parse_map, mask, _direction_face_up) + + +def _topmost_hair_y_per_col(mask: np.ndarray) -> np.ndarray: + """For each column return the smallest y where ``mask[y, x]`` is True, or -1.""" + H, W = mask.shape + cols_has = mask.any(axis=0) + out = np.full(W, -1, dtype=np.int32) + cols = np.where(cols_has)[0] + for x in cols: + out[x] = int(np.argmax(mask[:, x])) + return out + + +def sample_hairline_window( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + window_lateral_ratio: float = 0.05, + window_central_ratio: float = 0.015, + use_adjacent: bool = False, + fallback_extrapolation: float = 0.18, +) -> tuple[np.ndarray, np.ndarray]: + """For each anchor, search a horizontal window biased OUTWARD and snap to + the topmost hair pixel column inside it. + + Why this helps the 6/12-point problem: + The lateral-middle anchors (MP 54/103 on the left, MP 332/284 on the + right) sit on the forehead skin. A pure straight-up ray finds the top + of the hair plateau at the anchor's x — but the real "shoulder corner" + of the hairline is several pixels OUTWARD from the anchor. By widening + the search to a window that extends further toward the image edge, + these anchors can slide LATERALLY onto the actual shoulder. + + Per-anchor window: + [anchor_x - lateral_w, anchor_x + central_w] for LEFT anchors + [anchor_x - central_w, anchor_x + lateral_w] for RIGHT anchors + Center anchor (anchor.x ≈ face center) uses symmetric window. + + Both ``x`` and ``y`` of each output point are FREELY chosen inside the + window — the function returns the (col, top_y) of the topmost hair pixel. + """ + H, W = parse_map.shape + hair = ( + build_face_adjacent_hair_mask(parse_map) + if use_adjacent + else build_hair_mask(parse_map) + ) + top_y = _topmost_hair_y_per_col(hair) + up_norm = face_up_vector(landmarks_norm) + face_center_x = float(landmarks_norm[10, 0]) # MP 10 = forehead top + + w_lat = max(1, int(round(W * window_lateral_ratio))) + w_cen = max(1, int(round(W * window_central_ratio))) + + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + ax = int(round(np.clip(anchor_norm[0] * W, 0, W - 1))) + + side = 1 if anchor_norm[0] > face_center_x else (-1 if anchor_norm[0] < face_center_x else 0) + if side > 0: + x_lo = max(0, ax - w_cen) + x_hi = min(W, ax + w_lat + 1) + elif side < 0: + x_lo = max(0, ax - w_lat) + x_hi = min(W, ax + w_cen + 1) + else: + x_lo = max(0, ax - w_cen) + x_hi = min(W, ax + w_cen + 1) + + sub = top_y[x_lo:x_hi] + valid_cols = sub >= 0 + if not valid_cols.any(): + hairline[i] = (anchor_norm + up_norm * fallback_extrapolation).astype(np.float32) + continue + + sub_masked = np.where(valid_cols, sub, H + 1) + best_off = int(np.argmin(sub_masked)) + best_x = x_lo + best_off + best_y = int(sub[best_off]) + hairline[i, 0] = best_x / W + hairline[i, 1] = best_y / H + valid[i] = True + + return hairline, valid + + +def sample_hairline_window_adjacent(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """window 策略的 adjacent 变体: 候选 hair 必须邻接 face skin。""" + return sample_hairline_window(landmarks_norm, parse_map, use_adjacent=True) + + +def sample_hairline_lateral_extend( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + use_adjacent: bool = True, + outer_anchors_per_side: int = 3, + max_walk_ratio: float = 0.015, +) -> tuple[np.ndarray, np.ndarray]: + """baseline (+adjacent) 之后, 把最外侧 ``outer_anchors_per_side`` 个锚点 + 沿 hit 所在的横行向外侧推到真实的 hair 视觉边缘。 + + 动机 + ---- + 1, 2, 3 号 / 15, 16, 17 号锚点 (MP 127/234/162 和 389/356/454) 本来就长在 + 眉外角和耳前的皮肤上, 射线垂直向上停在 parser 给出的 hair 边界 —— 而 + parser 对侧鬓的边界比视觉上的 hair 边缘保守几个像素, 所以这些点看起来 + 比红线略微偏向脸内。 + + 这一步仅修改 X 坐标 (Y 保持 baseline hit 不变): 从 hit 像素出发, 沿同一 + 行向外 (远离脸部中心) 一步一步走, 只要下一像素还是 hair 就更新 X, 否则 + 停止。走距上限为 ``max_walk_ratio * W`` (默认 1.5%, ~11 px@734 宽); 太大 + 容易跑出可见 hair 之外 —— parser 会把侧鬓 / 头侧轮廓后面几像素也判成 hair, + 所以 1.5% 是相对保守的值。 + + 只对最外 ``outer_anchors_per_side`` 个锚点应用; 中间锚点保持 baseline。 + """ + if use_adjacent: + raw, valid = sample_hairline_adjacent(landmarks_norm, parse_map) + hair = build_face_adjacent_hair_mask(parse_map) + else: + raw, valid = sample_hairline_baseline(landmarks_norm, parse_map) + hair = build_hair_mask(parse_map) + + H, W = parse_map.shape + max_walk_px = max(2, int(round(W * max_walk_ratio))) + n = C.N_ANCHORS + + targets = ( + [(i, -1) for i in range(0, outer_anchors_per_side)] + + [(i, +1) for i in range(n - outer_anchors_per_side, n)] + ) + + for i, side in targets: + if not valid[i]: + continue + x_px = int(round(raw[i, 0] * W)) + y_px = int(round(raw[i, 1] * H)) + if y_px < 0 or y_px >= H: + continue + + x_outer = x_px + for step in range(1, max_walk_px + 1): + nx = x_px + step * side + if nx < 0 or nx >= W: + break + if hair[y_px, nx]: + x_outer = nx + else: + break + + raw[i, 0] = x_outer / W + + return raw, valid + + +def sample_hairline_lateral_extend_dense( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + intermediates: int = 1, + use_adjacent: bool = True, + max_walk_ratio: float = 0.015, + outer_per_side: int | None = None, + density_run_length: int = 0, + fallback_extrapolation: float = 0.18, +) -> tuple[np.ndarray, np.ndarray]: + """`lateral_extend` 的加密版本: 每对相邻 MP 锚点之间插入 ``intermediates`` 个 + 中间采样列, 再各自射线 + 横向延伸。 + + 总点数 = ``N_ANCHORS + (N_ANCHORS - 1) * intermediates`` + 默认 17 + 16 = **33 点**, 是原始 17 点密度的 ~2 倍。 + + 做法 + ---- + 1. 把 17 个 MP_TOP_ANCHORS 的归一化坐标按顺序线性插值, 在每对之间塞入 + ``intermediates`` 个等距中间种子。种子点 (x, y) 都在原 MP 锚点的连线上。 + 2. 每个种子点沿 face-up 方向直上, 命中首个 hair 像素 (用 adjacent hair + 过滤背景误分)。中间点的 y 来自其相邻两个原锚点的 y 内插, 起射高度 + 与真实锚点一致, 所以命中位置自然落在 hair 平台上。 + 3. 对最外侧 ``(intermediates + 1) * 3`` 个点 (覆盖原始 1-3 号 / 15-17 号 + 周围的加密点), 沿 hit 横行向外侧走最多 1.5% 图宽, 推到可见 hair 边缘。 + 4. 配合 corner-aware 平滑使用, 转角自动被保留。 + + 加密带来的两个直接收益 + ---- + * **6 号点和 12 号点之间的几个新点** (原始 5-6 / 12-13 之间) 会落在 + hair 平台的左上 / 右上转角处, 让发际线在角落处不再被两个稀疏的 MP + 点跨过。 + * 整条发际线更平滑, 同时 corner-aware 还能定位出新的转角。 + """ + if use_adjacent: + hair = build_face_adjacent_hair_mask(parse_map) + else: + hair = build_hair_mask(parse_map) + + H, W = parse_map.shape + up_norm = face_up_vector(landmarks_norm) + up_px = up_norm * np.array([W, H], dtype=np.float64) + up_px /= np.linalg.norm(up_px) + 1e-9 + + seeds: list[np.ndarray] = [] + for k in range(C.N_ANCHORS): + p_anchor = landmarks_norm[C.MP_TOP_ANCHORS[k], :2].astype(np.float64).copy() + seeds.append(p_anchor) + if k + 1 < C.N_ANCHORS: + p_next = landmarks_norm[C.MP_TOP_ANCHORS[k + 1], :2].astype(np.float64) + for j in range(1, intermediates + 1): + t = j / (intermediates + 1) + seeds.append((1.0 - t) * p_anchor + t * p_next) + + n_dense = len(seeds) + hairline = np.zeros((n_dense, 2), dtype=np.float32) + valid = np.zeros(n_dense, dtype=bool) + + for i, sn in enumerate(seeds): + anchor_px = sn * np.array([W, H], dtype=np.float64) + if density_run_length > 0: + hit_px = ray_first_dense_hit(anchor_px, up_px, hair, density_run_length) + else: + hit_px = ray_first_mask_hit(anchor_px, up_px, hair) + if hit_px is not None: + hairline[i] = (hit_px / np.array([W, H])).astype(np.float32) + valid[i] = True + else: + hairline[i] = (sn + up_norm * fallback_extrapolation).astype(np.float32) + + if outer_per_side is None: + outer = (intermediates + 1) * 3 + else: + outer = max(0, min(outer_per_side, n_dense // 2)) + targets = ( + [(i, -1) for i in range(0, outer)] + + [(i, +1) for i in range(n_dense - outer, n_dense)] + ) + max_walk_px = max(2, int(round(W * max_walk_ratio))) if max_walk_ratio > 0 else 0 + + if max_walk_px > 0: + for i, side in targets: + if not valid[i]: + continue + x_px = int(round(hairline[i, 0] * W)) + y_px = int(round(hairline[i, 1] * H)) + if y_px < 0 or y_px >= H: + continue + + x_outer = x_px + for step in range(1, max_walk_px + 1): + nx = x_px + step * side + if nx < 0 or nx >= W: + break + if hair[y_px, nx]: + x_outer = nx + else: + break + + hairline[i, 0] = x_outer / W + + return hairline, valid + + +def sample_hairline_converging(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """策略 3: 每个锚点的射线方向都收敛到头顶上方目标点。""" + mask = build_hair_mask(parse_map) + return _ray_sample_with_direction(landmarks_norm, parse_map, mask, _direction_converging) + + +def sample_hairline_converging_adjacent(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """策略 4: 收敛方向 + 邻接约束。""" + mask = build_face_adjacent_hair_mask(parse_map) + return _ray_sample_with_direction(landmarks_norm, parse_map, mask, _direction_converging) + + +def sample_hairline_boundary_proj(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """策略 5: 计算 hair-skin 边界曲线, 每个锚点投影到带方向约束的最近边界点。 + + "方向约束" 指: 候选边界点必须位于锚点的 face-up 方向之上 (cos(angle) >= 0), + 并且对横向偏移加额外惩罚, 避免吸到锚点正侧的边界。 + """ + import cv2 + + H, W = parse_map.shape + hair = np.isin(parse_map, [C.PARSE_HAIR, C.PARSE_HAT]).astype(np.uint8) + face = build_skin_mask(parse_map).astype(np.uint8) + face_dil = cv2.dilate(face, cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))) + boundary = (hair > 0) & (face_dil > 0) + + bys, bxs = np.where(boundary) + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + up_norm = face_up_vector(landmarks_norm) + up_px = up_norm * np.array([W, H], dtype=np.float64) + up_px /= np.linalg.norm(up_px) + 1e-9 + perp_px = np.array([-up_px[1], up_px[0]], dtype=np.float64) + + if bxs.size == 0: + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + hairline[i] = (anchor_norm + up_norm * 0.18).astype(np.float32) + return hairline, valid + + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + anchor_px = anchor_norm * np.array([W, H], dtype=np.float64) + dx = bxs - anchor_px[0] + dy = bys - anchor_px[1] + proj_up = dx * up_px[0] + dy * up_px[1] + keep = proj_up > 1.0 + if not keep.any(): + hairline[i] = (anchor_norm + up_norm * 0.18).astype(np.float32) + continue + d_up = proj_up[keep] + d_perp = np.abs(dx[keep] * perp_px[0] + dy[keep] * perp_px[1]) + cost = d_up + 2.5 * d_perp + local_best = int(np.argmin(cost)) + chosen = np.where(keep)[0][local_best] + hairline[i, 0] = bxs[chosen] / W + hairline[i, 1] = bys[chosen] / H + valid[i] = True + + return hairline, valid + + +def _ray_dense_sample( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + mask: np.ndarray, + direction_factory: Callable[[np.ndarray, np.ndarray, int, int], np.ndarray], + fallback_extrapolation: float = 0.18, + run_ratio: float = 0.06, +) -> tuple[np.ndarray, np.ndarray]: + """Density-stopping variant of :func:`_ray_sample_with_direction`.""" + H, W = parse_map.shape + run_length = density_run_length(landmarks_norm, W, H, run_ratio) + up_norm_fallback = face_up_vector(landmarks_norm) + + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + anchor_px = anchor_norm * np.array([W, H], dtype=np.float64) + direction_px = direction_factory(landmarks_norm, anchor_px, W, H) + hit_px = ray_first_dense_hit(anchor_px, direction_px, mask, run_length) + if hit_px is not None: + hairline[i] = (hit_px / np.array([W, H])).astype(np.float32) + valid[i] = True + else: + hairline[i] = (anchor_norm + up_norm_fallback * fallback_extrapolation).astype(np.float32) + valid[i] = False + return hairline, valid + + +def sample_hairline_density(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """密度策略 1: 沿 face-up 直上, 但要求连续 `density_run_length` 个 hair 像素才停。""" + mask = build_hair_mask(parse_map) + return _ray_dense_sample(landmarks_norm, parse_map, mask, _direction_face_up) + + +def sample_hairline_density_adjacent(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """密度策略 2: face-up + density + 邻接约束。""" + mask = build_face_adjacent_hair_mask(parse_map) + return _ray_dense_sample(landmarks_norm, parse_map, mask, _direction_face_up) + + +def sample_hairline_density_converging(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """密度策略 3: 收敛方向 + density。""" + mask = build_hair_mask(parse_map) + return _ray_dense_sample(landmarks_norm, parse_map, mask, _direction_converging) + + +def _ray_dense_inverse_sample( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + mask: np.ndarray, + target_scale: float = 1.5, + run_ratio: float = 0.06, + fallback_extrapolation: float = 0.18, +) -> tuple[np.ndarray, np.ndarray]: + """For each anchor, march FROM a target above the head DOWN toward the anchor. + + Density-based stopping returns the first dense hair pixel encountered. Since + the ray comes from outside/above the head, the first dense hair = top edge + of the head silhouette = actual hairline crown. This bypasses the side-hair + interception problem entirely for lateral anchors. + """ + H, W = parse_map.shape + run_length = density_run_length(landmarks_norm, W, H, run_ratio) + up_norm_fallback = face_up_vector(landmarks_norm) + + target_norm = head_top_target(landmarks_norm, scale=target_scale) + target_px = target_norm * np.array([W, H], dtype=np.float64) + + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + anchor_px = anchor_norm * np.array([W, H], dtype=np.float64) + direction = anchor_px - target_px + norm = float(np.linalg.norm(direction)) + 1e-9 + direction_unit = direction / norm + max_steps = int(norm) + 200 + hit_px = ray_first_dense_hit(target_px, direction_unit, mask, run_length, max_steps=max_steps) + accepted = False + if hit_px is not None: + t_along = float(np.dot(hit_px - target_px, direction_unit)) + if 0.0 < t_along < norm: + hairline[i] = (hit_px / np.array([W, H])).astype(np.float32) + valid[i] = True + accepted = True + if not accepted: + hairline[i] = (anchor_norm + up_norm_fallback * fallback_extrapolation).astype(np.float32) + return hairline, valid + + +def sample_hairline_density_inverse(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """密度策略 4: 反向射线 - 从头顶上方目标点向锚点扫, density stop。 + + 完全绕开 baseline 的核心痛点: 不再从锚点向上找头发, 而是从头部上方"找下来", + 第一段 dense hair 自然就是头部的上边缘 (冠状发际线)。 + """ + mask = build_hair_mask(parse_map) + return _ray_dense_inverse_sample(landmarks_norm, parse_map, mask) + + +def sample_hairline_density_inverse_adj(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """密度策略 5: 反向射线 + adjacent + density。""" + mask = build_face_adjacent_hair_mask(parse_map) + return _ray_dense_inverse_sample(landmarks_norm, parse_map, mask) + + +def sample_hairline_silhouette_at_anchor_x( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + window_radius_ratio: float = 0.01, +) -> tuple[np.ndarray, np.ndarray]: + """密度策略 6 (head silhouette 锚点对齐): 对每个 MP 锚点, 取它 x 列附近的头部上沿 y。 + + 与 ``top_arc`` 相比, 17 个点的 x 仍然跟 MediaPipe 锚点的 x 一一对应, + 但 y 直接来自 (face ∪ adjacent_hair) 在该 x 列的最高点 (最小 y), + 所以点会自然贴到头顶轮廓上, 形成冠状弧, 而不是被侧鬓拽下来。 + + window_radius_ratio: 用 anchor x 周围一小段窗口 (W·ratio) 取最小 y 做平滑。 + """ + H, W = parse_map.shape + head = build_skin_mask(parse_map) | build_face_adjacent_hair_mask(parse_map) + up_norm_fallback = face_up_vector(landmarks_norm) + + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + radius = max(1, int(round(W * window_radius_ratio))) + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + anchor_norm = landmarks_norm[mp_idx, :2] + cx = int(round(np.clip(anchor_norm[0] * W, 0, W - 1))) + x0 = max(0, cx - radius) + x1 = min(W, cx + radius + 1) + sub = head[:, x0:x1] + col_has = sub.any(axis=1) + if not col_has.any(): + hairline[i] = (anchor_norm + up_norm_fallback * 0.18).astype(np.float32) + continue + top_y = int(np.argmax(col_has)) + hairline[i, 0] = anchor_norm[0] + hairline[i, 1] = top_y / H + valid[i] = True + return hairline, valid + + +def _head_top_y_per_column( + parse_map: np.ndarray, + use_full_hair: bool = True, +) -> tuple[np.ndarray, np.ndarray]: + """Return (cols_with_head, top_y) where top_y[k] is the smallest y for which + ``head_mask[top_y[k], cols_with_head[k]]`` is True. + + ``use_full_hair=True`` uses the FULL hair mask (proper head silhouette); + pass ``False`` to fall back to the face-adjacent strip only. + """ + if use_full_hair: + head = build_skin_mask(parse_map) | build_hair_mask(parse_map) + else: + head = build_skin_mask(parse_map) | build_face_adjacent_hair_mask(parse_map) + cols_with_head = np.where(head.any(axis=0))[0] + if cols_with_head.size == 0: + return cols_with_head, np.array([], dtype=np.int32) + top_y = np.empty(cols_with_head.size, dtype=np.int32) + for j, x in enumerate(cols_with_head): + top_y[j] = int(np.argmax(head[:, x])) + return cols_with_head, top_y + + +def sample_hairline_arch( + landmarks_norm: np.ndarray, + parse_map: np.ndarray, + central_drop: int = 3, + require_lift_px_ratio: float = 0.02, + density_ratio: float = 0.03, + use_adjacent_for_central: bool = False, +) -> tuple[np.ndarray, np.ndarray]: + """冠状弧 (coronal arch) 策略 — 从一只耳朵上方画到另一只耳朵上方。 + + 流程 + ---- + 1. 中间 ``N_ANCHORS - 2*central_drop`` 个锚点(默认丢掉颧骨/太阳穴附近的 6 个), + 沿 face-up 做密度门限射线,命中 ``run_length`` 个连续 hair 像素的入口作为 + 真实发际线点。``run_length = face_height * density_ratio``。 + 2. 拒掉那些 hit 离锚点向上不到 ``face_height * require_lift_px_ratio`` + 的,它们多半是侧鬓或假阳性。 + 3. 取整个头部 (face ∪ 全部 hair) 的 silhouette:在最左 / 最右极限列上, + 记录 silhouette 上沿点。这两个点是耳朵上方的曲线终点。 + 4. 控制点 = [左极限 silhouette] + [中间锚点真实 hit] + [右极限 silhouette], + 按 x 排序,线性插值到 17 个等距输出 x。 + 5. 钳位:任何输出 y 都不能比该 x 处头部 silhouette 上沿还小,避免曲线 + 跑到头顶上方的虚空里去。 + 6. 上层 web_service 会再调用 ``smooth_hairline`` 平滑一遍。 + + 生成的 17 个点 x 均匀覆盖整个头部宽度(从左耳上方到右耳上方),中间 y 贴近 + 真实发际线、两侧 y 自然抬升到头部 silhouette 上沿,形成冠状弧。它们的 x + 不再与对应 MP_TOP_ANCHORS 一一对应,但顺序保持一致。 + """ + H, W = parse_map.shape + hair_for_rays = ( + build_face_adjacent_hair_mask(parse_map) + if use_adjacent_for_central + else build_hair_mask(parse_map) + ) + run_length = max(4, int(round(_face_height_px(landmarks_norm, W, H) * density_ratio))) + up_norm = face_up_vector(landmarks_norm) + up_px = up_norm * np.array([W, H], dtype=np.float64) + up_px /= np.linalg.norm(up_px) + 1e-9 + + face_h_px = _face_height_px(landmarks_norm, W, H) + min_lift = face_h_px * require_lift_px_ratio + + # Step 1: central density-ray hits + central_indices = range(central_drop, C.N_ANCHORS - central_drop) + central_hits: list[tuple[float, float]] = [] + for i in central_indices: + mp_idx = C.MP_TOP_ANCHORS[i] + anchor_px = landmarks_norm[mp_idx, :2] * np.array([W, H], dtype=np.float64) + hit = ray_first_dense_hit(anchor_px, up_px, hair_for_rays, run_length) + if hit is None: + continue + # signed distance "up" from anchor to hit (positive when hit is above anchor) + delta_up = float(np.dot(hit - anchor_px, up_px)) + if delta_up < min_lift: + continue + central_hits.append((float(hit[0]), float(hit[1]))) + + # Step 2: head silhouette + cols_with_head, top_y = _head_top_y_per_column(parse_map, use_full_hair=True) + if cols_with_head.size < 2: + return sample_hairline_baseline(landmarks_norm, parse_map) + + left_x = float(cols_with_head[0]) + right_x = float(cols_with_head[-1]) + + def silhouette_y_at(x_px: float) -> float: + idx = int(round(np.clip(x_px, left_x, right_x))) + k = int(np.searchsorted(cols_with_head, idx)) + k = min(k, cols_with_head.size - 1) + return float(top_y[k]) + + if not central_hits: + # No reliable central hits — fall back to silhouette top across the head + # (still a coronal arc, just less precise on the forehead) + output_xs = np.linspace(left_x, right_x, C.N_ANCHORS) + output_ys = np.array([silhouette_y_at(float(x)) for x in output_xs], dtype=np.float64) + hairline = np.column_stack([output_xs / W, output_ys / H]).astype(np.float32) + return hairline, np.ones(C.N_ANCHORS, dtype=bool) + + # Step 3: control points = [left endpoint] + central hits + [right endpoint] + control_pts: list[tuple[float, float]] = list(central_hits) + control_pts.append((left_x, silhouette_y_at(left_x))) + control_pts.append((right_x, silhouette_y_at(right_x))) + + # Step 4: sort + dedupe by x, then linear-interp 17 evenly-spaced output xs + cps = sorted(control_pts, key=lambda p: p[0]) + cxs = [cps[0][0]] + cys = [cps[0][1]] + for x, y in cps[1:]: + if x - cxs[-1] < 0.5: + # collision: prefer the LARGER y (the actual hairline, not silhouette) + cys[-1] = max(cys[-1], y) + else: + cxs.append(x) + cys.append(y) + cxs_arr = np.asarray(cxs, dtype=np.float64) + cys_arr = np.asarray(cys, dtype=np.float64) + output_xs = np.linspace(left_x, right_x, C.N_ANCHORS) + output_ys = np.interp(output_xs, cxs_arr, cys_arr) + + # Step 5: hairline cannot be above the head silhouette top + for k, x in enumerate(output_xs): + sil_y = silhouette_y_at(float(x)) + if output_ys[k] < sil_y: + output_ys[k] = sil_y + + hairline = np.column_stack([output_xs / W, output_ys / H]).astype(np.float32) + valid = np.ones(C.N_ANCHORS, dtype=bool) + return hairline, valid + + +def sample_hairline_arch_strict(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """冠状弧策略 (严格版): 只用中间 5 个最可靠的额头锚点; 同时要求 hit 离锚点更远。 + + 适合中间锚点也容易被刘海/眉毛干扰的场景,曲线更"瘦高"。 + """ + return sample_hairline_arch( + landmarks_norm, + parse_map, + central_drop=6, # 只保留中间 5 个锚点 + require_lift_px_ratio=0.04, + density_ratio=0.04, + ) + + +def sample_hairline_arch_adj(landmarks_norm: np.ndarray, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """冠状弧策略 (邻接版): 中间锚点的射线只命中"贴脸"的 hair 像素。 + + 更不容易被远离脸部的背景或后脑勺误命中,但要求 face-adjacent hair 必须 + 形成连续 ``run_length`` 像素 (默认 ratio=0.025) 的密度。 + """ + return sample_hairline_arch( + landmarks_norm, + parse_map, + central_drop=3, + require_lift_px_ratio=0.015, + density_ratio=0.025, + use_adjacent_for_central=True, + ) + + +def sample_hairline_top_arc(landmarks_norm, parse_map: np.ndarray) -> tuple[np.ndarray, np.ndarray]: + """策略 6: 不用锚点, 取 (face ∪ adjacent_hair) 的上沿, 按 x 等距 17 点。 + + ``landmarks_norm`` 仅用于 fallback 并允许传 None。 + """ + H, W = parse_map.shape + head = build_skin_mask(parse_map) | build_face_adjacent_hair_mask(parse_map) + hairline = np.zeros((C.N_ANCHORS, 2), dtype=np.float32) + valid = np.zeros((C.N_ANCHORS,), dtype=bool) + + cols_with_head = np.where(head.any(axis=0))[0] + if cols_with_head.size < 2: + return hairline, valid + + top_y = np.empty(cols_with_head.size, dtype=np.int32) + for j, x in enumerate(cols_with_head): + top_y[j] = int(np.argmax(head[:, x])) + + left, right = int(cols_with_head[0]), int(cols_with_head[-1]) + xs = np.linspace(left, right, C.N_ANCHORS) + ys = np.interp(xs, cols_with_head.astype(np.float64), top_y.astype(np.float64)) + hairline[:, 0] = xs / W + hairline[:, 1] = ys / H + valid[:] = True + return hairline, valid diff --git a/hairline/lift_3d.py b/hairline/lift_3d.py new file mode 100644 index 0000000..17c68d2 --- /dev/null +++ b/hairline/lift_3d.py @@ -0,0 +1,133 @@ +"""Lift 2D hairline samples to 3D in MediaPipe's normalized space. + +Saggital-arc Z model +-------------------- +MediaPipe / face.obj use ``-z = front of face`` (nose tip is the most +negative z), ``+z = back of head``. The frontal head surface curves +backward as you move up from the forehead to the crown, so any vertex +**above** an MP top anchor (smaller y in image coords) must have a +**larger** z than that anchor. + +For each new hairline / middle vertex (x_h, y_h) attached to MP anchor a +located at (x_a, y_a, z_a), we model the local sagittal cross-section +of the head as a circular arc of radius ``R = HEAD_ARC_RADIUS_FRAC × face_h`` +and derive + + z_new = z_a + (y_h - y_a)² / (2 R) + +The squared dy term guarantees ``z_new ≥ z_a`` (the surface always +bulges backward as you walk up the head, never forward). x is taken +directly from the 2D hairline detection (we don't project x onto the +arc — the parsing tells us exactly where the hairline sits in x). +""" +from __future__ import annotations +import numpy as np + +from . import constants as C +from .hairline_2d import face_up_vector + + +def _face_height(landmarks_norm: np.ndarray) -> float: + """Range of MP y for the visible face (used for the arc radius).""" + y = landmarks_norm[:, 1] + return float(y.max() - y.min()) + + +def _arc_dz(dy: float, R: float) -> float: + """Backward (positive) z offset along a circular arc of radius R for + a vertical displacement dy. Always non-negative.""" + return (dy * dy) / (2.0 * max(R, 1e-6)) + + +def lift_hairline_to_3d( + landmarks_norm: np.ndarray, + hairline_norm_xy: np.ndarray, + crown_lift_frac: float | None = None, +) -> np.ndarray: + """Combine 2D hairline samples with a sagittal-arc Z, after lifting + the (x, y) along the face-up direction by ``crown_lift_frac × face_h`` + so the ribbon's top row sits at the crown of the head rather than at + the detected hair-skin boundary. + + landmarks_norm: (468, 3) MediaPipe normalized landmarks. + hairline_norm_xy: (N_ANCHORS, 2) 2D hairline samples in [0,1] image space. + crown_lift_frac: how far above the detected hairline (in fractions of + face height) the mesh row should sit. ``None`` uses + ``C.HAIRLINE_CROWN_LIFT_FRAC``. + Returns: (N_ANCHORS, 3) — (x_norm_lifted, y_norm_lifted, z). + """ + face_h = _face_height(landmarks_norm) + R = C.HEAD_ARC_RADIUS_FRAC * face_h + if crown_lift_frac is None: + crown_lift_frac = C.HAIRLINE_CROWN_LIFT_FRAC + up = face_up_vector(landmarks_norm) + lift = up * (crown_lift_frac * face_h) # 2D offset, face-up direction + + out = np.zeros((C.N_ANCHORS, 3), dtype=np.float32) + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + z_a = float(landmarks_norm[mp_idx, 2]) + y_a = float(landmarks_norm[mp_idx, 1]) + x_h = float(hairline_norm_xy[i, 0]) + float(lift[0]) + y_h = float(hairline_norm_xy[i, 1]) + float(lift[1]) + dy = y_h - y_a # < 0 (上移更多 → dz 更大) + out[i, 0] = x_h + out[i, 1] = y_h + out[i, 2] = z_a + _arc_dz(dy, R) + return out + + +def build_middle_row( + landmarks_norm: np.ndarray, + hairline_3d: np.ndarray, + bias: float = 0.5, +) -> np.ndarray: + """Place the middle row at the arc-length midpoint between each MP + anchor and its hairline point. + + The old approach used bias=0.5 linear interpolation in XY and then + independently recomputed Z via the arc formula. Because dz ∝ dy², + the middle row only received 25 % of the hairline Z offset, creating + a visible dent where the extension met the face mesh. + + New approach: for each anchor→hairline pair, parameterise the + sagittal circular arc by the angle θ and place the middle vertex at + θ_mid = bias × θ_hair. This distributes both the Y displacement + **and** the Z displacement smoothly along the arc, so the surface + transitions from the face mesh through middle to hairline without + any concavity. + """ + R = C.HEAD_ARC_RADIUS_FRAC * _face_height(landmarks_norm) + out = np.zeros((C.N_ANCHORS, 3), dtype=np.float32) + for i, mp_idx in enumerate(C.MP_TOP_ANCHORS): + a = landmarks_norm[mp_idx] + h = hairline_3d[i] + # X: simple linear interpolation (no arc model in the coronal plane) + out[i, 0] = (1 - bias) * float(a[0]) + bias * float(h[0]) + # Y, Z: interpolate along the circular arc in the sagittal plane. + # The arc angle for the hairline point: + # θ_h = |dy_h| / R (small-angle: arc-length ≈ R θ) + # Middle sits at θ_m = bias × θ_h, giving: + # dy_m = R sin(θ_m) ≈ R θ_m for small θ + # dz_m = R (1 − cos(θ_m)) + # For the parabolic regime (θ < 0.8 rad ≈ 46°) these simplify to + # the same formula but we use the full trig for correctness. + dy_h = float(h[1]) - float(a[1]) # negative (upward) + sign = -1.0 if dy_h < 0 else 1.0 + theta_h = abs(dy_h) / max(R, 1e-9) + theta_m = bias * theta_h + dy_m = sign * R * np.sin(theta_m) # same sign as dy_h + dz_m = R * (1.0 - np.cos(theta_m)) # always ≥ 0 + out[i, 1] = float(a[1]) + dy_m + out[i, 2] = float(a[2]) + dz_m + return out + + +def assemble_full(landmarks_norm: np.ndarray, + middle_3d: np.ndarray, + hairline_3d: np.ndarray) -> np.ndarray: + """Concatenate to a (N_TOTAL, 3) array in the SDK's expected order: + [0..468) MediaPipe / [468..485) middle / [485..502) hairline.""" + assert landmarks_norm.shape == (C.N_MP, 3) + assert middle_3d.shape == (C.N_ANCHORS, 3) + assert hairline_3d.shape == (C.N_ANCHORS, 3) + return np.concatenate([landmarks_norm, middle_3d, hairline_3d], axis=0).astype(np.float32) diff --git a/hairline/mesh/face.obj b/hairline/mesh/face.obj new file mode 100644 index 0000000..a4c9eac --- /dev/null +++ b/hairline/mesh/face.obj @@ -0,0 +1,2279 @@ +# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware +# ļ:02.12.2025 18:33:58 + +mtllib 1202.mtl + +# +# object default +# + +v 0.1676 0.5092 0.2591 +v 0.1771 0.5141 0.1685 +v 0.1865 0.4618 0.1361 +v 0.4670 0.7575 -0.0631 +v 0.4671 0.7458 -0.0670 +v 0.4379 0.7395 -0.0631 +v 0.3892 0.5426 -0.0007 +v 0.3631 0.5501 0.0018 +v 0.3648 0.5691 -0.0028 +v 0.4383 0.7547 -0.0594 +v 0.4080 0.7493 -0.0466 +v 0.4142 0.5453 -0.0172 +v 0.3929 0.5585 -0.0115 +v 0.3953 0.5777 -0.0249 +v 0.2693 0.3555 -0.0041 +v 0.3317 0.3441 -0.0417 +v 0.3176 0.2901 -0.0208 +v 0.4645 0.9425 0.0141 +v 0.4131 0.9359 0.0208 +v 0.4148 0.9524 0.0567 +v 0.2764 0.5811 0.0178 +v 0.2618 0.6372 0.0203 +v 0.3218 0.6083 -0.0036 +v 0.4130 0.7599 -0.0441 +v 0.3882 0.7597 -0.0267 +v 0.4716 0.4160 -0.0756 +v 0.4717 0.3448 -0.0701 +v 0.3976 0.3432 -0.0630 +v 0.3969 0.6604 -0.0717 +v 0.4082 0.6504 -0.0986 +v 0.4081 0.6340 -0.0898 +v 0.3866 0.8650 0.0146 +v 0.3576 0.8424 0.0268 +v 0.3437 0.8641 0.0496 +v 0.3940 0.7654 -0.0259 +v 0.3753 0.7689 -0.0041 +v 0.4042 0.7765 -0.0144 +v 0.3997 0.7722 -0.0205 +v 0.3858 0.7742 -0.0038 +v 0.3656 0.7335 -0.0192 +v 0.3465 0.7519 0.0005 +v 0.3297 0.5547 0.0078 +v 0.2951 0.5537 0.0195 +v 0.3330 0.8122 0.0361 +v 0.3121 0.7799 0.0363 +v 0.2817 0.7829 0.0643 +v 0.4327 0.8532 -0.0060 +v 0.4654 0.8552 -0.0070 +v 0.4656 0.8296 -0.0366 +v 0.3696 0.7768 0.0149 +v 0.3665 0.7770 0.0190 +v 0.3761 0.7887 0.0050 +v 0.3077 0.4839 0.0049 +v 0.2906 0.4595 -0.0031 +v 0.2739 0.4710 0.0089 +v 0.3790 0.4711 -0.0057 +v 0.3737 0.4919 0.0003 +v 0.3911 0.5057 0.0066 +v 0.3754 0.8206 0.0083 +v 0.2726 0.8255 0.1227 +v 0.2492 0.7539 0.0989 +v 0.3648 0.6781 -0.0133 +v 0.3913 0.7208 -0.0338 +v 0.4049 0.6867 -0.0353 +v 0.1839 0.3975 0.1474 +v 0.2000 0.4179 0.0893 +v 0.2271 0.3808 0.0385 +v 0.4461 0.6108 -0.1335 +v 0.4449 0.6420 -0.1470 +v 0.4683 0.6424 -0.1505 +v 0.3130 0.5174 0.0122 +v 0.3092 0.5328 0.0113 +v 0.3340 0.5345 0.0034 +v 0.3805 0.7832 0.0001 +v 0.3891 0.8008 -0.0126 +v 0.3002 0.6720 -0.0008 +v 0.2473 0.6924 0.0531 +v 0.4243 0.8807 0.0009 +v 0.4652 0.8852 -0.0044 +v 0.4008 0.8398 -0.0021 +v 0.3934 0.7913 -0.0180 +v 0.4090 0.8158 -0.0252 +v 0.4368 0.8081 -0.0399 +v 0.4355 0.8259 -0.0348 +v 0.3387 0.7021 -0.0061 +v 0.3413 0.6423 -0.0146 +v 0.3707 0.9171 0.0457 +v 0.4398 0.4946 -0.0439 +v 0.4163 0.4924 -0.0098 +v 0.4205 0.5208 -0.0087 +v 0.3286 0.4800 -0.0027 +v 0.3507 0.4822 -0.0044 +v 0.3507 0.4573 -0.0138 +v 0.2650 0.4848 0.0259 +v 0.2885 0.4959 0.0245 +v 0.2953 0.4902 0.0145 +v 0.4299 0.5952 -0.0907 +v 0.4478 0.5842 -0.1103 +v 0.4469 0.5590 -0.0919 +v 0.2100 0.3506 0.0899 +v 0.4704 0.4907 -0.0625 +v 0.4708 0.4538 -0.0666 +v 0.2438 0.5706 0.0425 +v 0.2694 0.5454 0.0357 +v 0.2547 0.5342 0.0489 +v 0.4147 0.4479 -0.0578 +v 0.4381 0.6925 -0.0621 +v 0.4358 0.6881 -0.0632 +v 0.3997 0.6049 -0.0340 +v 0.3666 0.5924 -0.0138 +v 0.4158 0.6704 -0.0715 +v 0.4240 0.6662 -0.0985 +v 0.4162 0.6618 -0.1040 +v 0.3915 0.5162 0.0115 +v 0.3762 0.5164 0.0068 +v 0.3827 0.5290 0.0029 +v 0.4015 0.6264 -0.0480 +v 0.3951 0.6468 -0.0647 +v 0.2745 0.8529 0.1747 +v 0.3121 0.8883 0.1365 +v 0.4156 0.5873 -0.0517 +v 0.3094 0.4427 -0.0210 +v 0.2958 0.4235 -0.0338 +v 0.2595 0.4320 -0.0112 +v 0.4257 0.6190 -0.1166 +v 0.3369 0.8887 0.0738 +v 0.3553 0.8012 0.0189 +v 0.3268 0.5785 0.0047 +v 0.2483 0.5082 0.0545 +v 0.2680 0.5023 0.0429 +v 0.2444 0.4142 0.0007 +v 0.4447 0.6760 -0.1132 +v 0.4468 0.6819 -0.0886 +v 0.4518 0.6855 -0.0880 +v 0.2345 0.4506 0.0166 +v 0.2186 0.4376 0.0384 +v 0.2080 0.4730 0.0733 +v 0.3758 0.7767 0.0109 +v 0.3724 0.7765 0.0115 +v 0.3860 0.7805 -0.0004 +v 0.2017 0.5181 0.1021 +v 0.1794 0.5700 0.1817 +v 0.2078 0.6235 0.0945 +v 0.2264 0.5516 0.0656 +v 0.4481 0.6677 -0.1374 +v 0.4565 0.6808 -0.1238 +v 0.4680 0.6820 -0.1255 +v 0.3186 0.7336 0.0088 +v 0.3551 0.5186 0.0035 +v 0.3600 0.5332 0.0009 +v 0.4362 0.7131 -0.0588 +v 0.4161 0.9117 0.0047 +v 0.3756 0.6237 -0.0222 +v 0.3370 0.7750 0.0229 +v 0.4334 0.6829 -0.0627 +v 0.2232 0.5152 0.0750 +v 0.2488 0.4835 0.0338 +v 0.3185 0.4537 -0.0130 +v 0.3124 0.8326 0.0644 +v 0.2574 0.4627 0.0097 +v 0.1892 0.6268 0.1920 +v 0.2004 0.5675 0.0971 +v 0.4176 0.7696 -0.0389 +v 0.4403 0.7685 -0.0495 +v 0.3885 0.6596 -0.0216 +v 0.3968 0.6721 -0.0561 +v 0.4127 0.6839 -0.0509 +v 0.3910 0.6586 -0.0486 +v 0.2811 0.7127 0.0235 +v 0.3801 0.7717 -0.0038 +v 0.3058 0.8611 0.0987 +v 0.3436 0.9132 0.1068 +v 0.3766 0.9355 0.0767 +v 0.2857 0.4006 -0.0310 +v 0.3413 0.4028 -0.0575 +v 0.4461 0.5307 -0.0678 +v 0.4702 0.5253 -0.0786 +v 0.2170 0.6766 0.1074 +v 0.3464 0.4269 -0.0501 +v 0.4055 0.4113 -0.0715 +v 0.3989 0.7829 -0.0152 +v 0.4124 0.7997 -0.0300 +v 0.1829 0.6285 0.2903 +v 0.4662 0.7941 -0.0388 +v 0.4395 0.7914 -0.0353 +v 0.4667 0.7799 -0.0380 +v 0.4429 0.7777 -0.0344 +v 0.3334 0.5197 0.0053 +v 0.4044 0.7768 -0.0132 +v 0.4168 0.7866 -0.0268 +v 0.3914 0.7770 0.0008 +v 0.2412 0.7896 0.1540 +v 0.2439 0.8140 0.2214 +v 0.2163 0.7403 0.1861 +v 0.2171 0.7611 0.2620 +v 0.4046 0.6684 -0.0743 +v 0.4218 0.7757 -0.0259 +v 0.4693 0.5807 -0.1203 +v 0.4645 0.9176 -0.0027 +v 0.4427 0.7770 -0.0354 +v 0.3002 0.5130 0.0210 +v 0.2904 0.5279 0.0232 +v 0.1733 0.5677 0.2835 +v 0.3888 0.2791 -0.0510 +v 0.4062 0.6759 -0.0606 +v 0.3911 0.7769 -0.0000 +v 0.3491 0.4463 -0.0240 +v 0.4591 0.6886 -0.0877 +v 0.3948 0.4651 -0.0194 +v 0.4693 0.5547 -0.0987 +v 0.2793 0.5182 0.0339 +v 0.2917 0.5082 0.0285 +v 0.2830 0.5012 0.0372 +v 0.4253 0.6445 -0.1239 +v 0.4322 0.6630 -0.1245 +v 0.4292 0.5259 -0.0266 +v 0.1712 0.4480 0.2091 +v 0.4299 0.5441 -0.0501 +v 0.4302 0.5711 -0.0722 +v 0.4679 0.6942 -0.0697 +v 0.4487 0.6788 -0.1199 +v 0.4677 0.7135 -0.0618 +v 0.4672 0.7696 -0.0536 +v 0.4666 0.7789 -0.0387 +v 0.4143 0.6117 -0.0684 +v 0.3989 0.5145 0.0114 +v 0.3979 0.5234 0.0058 +v 0.4074 0.5155 0.0073 +v 0.4330 0.6672 -0.1115 +v 0.4015 0.4957 0.0009 +v 0.3750 0.8914 0.0272 +v 0.4221 0.7771 -0.0248 +v 0.1977 0.6930 0.2835 +v 0.2017 0.6854 0.1930 +v 0.4680 0.6685 -0.1399 +v 0.2263 0.7213 0.1205 +v 0.4161 0.6751 -0.0607 +v 0.4679 0.6893 -0.0895 +v 0.4217 0.6803 -0.0551 +v 0.2780 0.4493 -0.0086 +v 0.4070 0.5352 -0.0034 +v 0.4134 0.5615 -0.0359 +v 0.2270 0.4800 0.0463 +v 0.7744 0.5149 0.2502 +v 0.7717 0.4527 0.2009 +v 0.7564 0.4666 0.1289 +v 0.4961 0.7564 -0.0603 +v 0.4968 0.7409 -0.0641 +v 0.5513 0.5446 -0.0028 +v 0.5470 0.5601 -0.0137 +v 0.5759 0.5717 -0.0057 +v 0.5217 0.7633 -0.0460 +v 0.5265 0.7526 -0.0487 +v 0.5263 0.5464 -0.0187 +v 0.5258 0.5628 -0.0376 +v 0.5440 0.5794 -0.0271 +v 0.5326 0.5370 -0.0051 +v 0.6749 0.3576 -0.0091 +v 0.6914 0.3169 0.0245 +v 0.6266 0.2923 -0.0250 +v 0.4644 0.9578 0.0484 +v 0.5151 0.9534 0.0552 +v 0.6655 0.5852 0.0127 +v 0.6148 0.5816 0.0010 +v 0.6177 0.6115 -0.0074 +v 0.5414 0.7702 -0.0285 +v 0.5470 0.7642 -0.0296 +v 0.5384 0.4118 -0.0725 +v 0.5462 0.3442 -0.0649 +v 0.5404 0.6625 -0.0737 +v 0.5420 0.6489 -0.0668 +v 0.5294 0.6356 -0.0915 +v 0.5463 0.8663 0.0123 +v 0.5572 0.8928 0.0248 +v 0.5904 0.8660 0.0460 +v 0.5546 0.7769 -0.0072 +v 0.5597 0.7746 -0.0078 +v 0.5303 0.7798 -0.0166 +v 0.5433 0.7812 -0.0029 +v 0.5494 0.7797 -0.0068 +v 0.5895 0.7566 -0.0036 +v 0.6114 0.5583 0.0040 +v 0.6029 0.8160 0.0321 +v 0.6222 0.8358 0.0597 +v 0.6549 0.7875 0.0586 +v 0.4990 0.8532 -0.0067 +v 0.4972 0.8271 -0.0358 +v 0.5660 0.7828 0.0113 +v 0.5545 0.7887 -0.0031 +v 0.5593 0.7932 0.0014 +v 0.6346 0.4869 0.0005 +v 0.6476 0.4942 0.0098 +v 0.6703 0.4744 0.0038 +v 0.5633 0.4724 -0.0083 +v 0.5397 0.4974 -0.0014 +v 0.5495 0.5072 0.0040 +v 0.5582 0.8234 0.0052 +v 0.5322 0.8411 -0.0042 +v 0.6630 0.8297 0.1167 +v 0.6946 0.7937 0.1473 +v 0.6879 0.7587 0.0926 +v 0.5719 0.6809 -0.0160 +v 0.5485 0.6618 -0.0238 +v 0.5309 0.6890 -0.0369 +v 0.7595 0.4019 0.1394 +v 0.7337 0.3543 0.0828 +v 0.7165 0.3837 0.0323 +v 0.4907 0.6108 -0.1342 +v 0.4686 0.6085 -0.1422 +v 0.6285 0.5216 0.0079 +v 0.6083 0.5236 0.0014 +v 0.6071 0.5388 -0.0005 +v 0.5410 0.7954 -0.0205 +v 0.5457 0.8047 -0.0151 +v 0.6384 0.6759 -0.0051 +v 0.6567 0.7166 0.0184 +v 0.6916 0.6970 0.0471 +v 0.5070 0.8820 -0.0003 +v 0.5247 0.8179 -0.0270 +v 0.5220 0.8031 -0.0318 +v 0.4960 0.8096 -0.0407 +v 0.4663 0.8117 -0.0427 +v 0.5989 0.7052 -0.0097 +v 0.5967 0.6454 -0.0179 +v 0.5548 0.9369 0.0738 +v 0.5614 0.9182 0.0429 +v 0.5700 0.7367 -0.0225 +v 0.5441 0.7234 -0.0362 +v 0.5007 0.4954 -0.0448 +v 0.5116 0.5273 -0.0278 +v 0.5196 0.5223 -0.0099 +v 0.6141 0.4824 -0.0067 +v 0.6251 0.4559 -0.0172 +v 0.5922 0.4593 -0.0170 +v 0.6544 0.5000 0.0197 +v 0.5084 0.5956 -0.0919 +v 0.5087 0.5722 -0.0734 +v 0.4922 0.5595 -0.0925 +v 0.5285 0.4483 -0.0589 +v 0.6986 0.5752 0.0364 +v 0.7160 0.5567 0.0593 +v 0.6877 0.5382 0.0432 +v 0.5248 0.4937 -0.0115 +v 0.5480 0.4664 -0.0217 +v 0.5237 0.6857 -0.0523 +v 0.4998 0.6891 -0.0639 +v 0.5391 0.6066 -0.0361 +v 0.5629 0.6260 -0.0248 +v 0.5726 0.5943 -0.0166 +v 0.5205 0.6722 -0.0730 +v 0.5317 0.6708 -0.0760 +v 0.5198 0.6630 -0.1055 +v 0.5495 0.5184 0.0091 +v 0.5428 0.5258 0.0035 +v 0.5577 0.5312 0.0005 +v 0.5364 0.6280 -0.0500 +v 0.5238 0.6125 -0.0700 +v 0.6281 0.8636 0.0938 +v 0.6213 0.8908 0.1315 +v 0.5232 0.5884 -0.0534 +v 0.6352 0.4452 -0.0248 +v 0.6668 0.4522 -0.0132 +v 0.6867 0.4338 -0.0162 +v 0.4918 0.6432 -0.1477 +v 0.5114 0.6456 -0.1254 +v 0.5115 0.6200 -0.1179 +v 0.5553 0.2800 -0.0530 +v 0.5789 0.8055 0.0152 +v 0.5774 0.5527 -0.0012 +v 0.6946 0.5128 0.0488 +v 0.6953 0.4875 0.0281 +v 0.6793 0.4888 0.0205 +v 0.7019 0.4160 -0.0048 +v 0.6604 0.4020 -0.0352 +v 0.6497 0.4245 -0.0376 +v 0.4912 0.6765 -0.1137 +v 0.4866 0.6789 -0.1205 +v 0.4840 0.6866 -0.0884 +v 0.7115 0.4529 0.0107 +v 0.7171 0.4838 0.0400 +v 0.7369 0.4771 0.0664 +v 0.5594 0.7825 0.0073 +v 0.5439 0.7814 -0.0022 +v 0.5485 0.7852 -0.0035 +v 0.7270 0.4401 0.0327 +v 0.7415 0.5225 0.0958 +v 0.7419 0.5721 0.0907 +v 0.7620 0.5753 0.1738 +v 0.7328 0.6288 0.0872 +v 0.4875 0.6683 -0.1379 +v 0.4904 0.5846 -0.1110 +v 0.6180 0.7377 0.0042 +v 0.5643 0.5195 0.0040 +v 0.5813 0.5365 -0.0023 +v 0.4993 0.7142 -0.0598 +v 0.5151 0.9128 0.0035 +v 0.5984 0.7794 0.0184 +v 0.4892 0.6825 -0.0891 +v 0.5669 0.4936 -0.0026 +v 0.7203 0.5196 0.0686 +v 0.6533 0.4625 -0.0078 +v 0.5766 0.8444 0.0235 +v 0.5623 0.7825 0.0079 +v 0.7520 0.6314 0.1844 +v 0.5167 0.7730 -0.0406 +v 0.5400 0.6741 -0.0581 +v 0.5303 0.6776 -0.0624 +v 0.5353 0.7759 -0.0228 +v 0.6239 0.7833 0.0314 +v 0.5960 0.8909 0.0700 +v 0.6122 0.3457 -0.0448 +v 0.4938 0.5309 -0.0685 +v 0.6776 0.6411 0.0149 +v 0.5357 0.7863 -0.0175 +v 0.5982 0.4280 -0.0528 +v 0.6040 0.4038 -0.0603 +v 0.5174 0.7896 -0.0284 +v 0.7582 0.6342 0.2818 +v 0.7690 0.5736 0.2749 +v 0.4943 0.7922 -0.0363 +v 0.5854 0.5220 0.0003 +v 0.5304 0.7802 -0.0155 +v 0.5130 0.7792 -0.0265 +v 0.6597 0.8562 0.1685 +v 0.7211 0.7447 0.1787 +v 0.6912 0.8179 0.2141 +v 0.5286 0.6525 -0.1003 +v 0.5129 0.7787 -0.0275 +v 0.5682 0.7832 0.0151 +v 0.5171 0.9373 0.0194 +v 0.4939 0.7699 -0.0503 +v 0.6871 0.4657 0.0044 +v 0.6327 0.5371 0.0068 +v 0.6520 0.5319 0.0182 +v 0.6466 0.5575 0.0148 +v 0.7649 0.5192 0.1610 +v 0.4720 0.2776 -0.0588 +v 0.5948 0.4476 -0.0270 +v 0.4767 0.6883 -0.0879 +v 0.6595 0.5052 0.0319 +v 0.6627 0.5227 0.0286 +v 0.6748 0.5067 0.0376 +v 0.5094 0.5448 -0.0511 +v 0.7436 0.4215 0.0823 +v 0.5889 0.9153 0.1029 +v 0.4976 0.6930 -0.0628 +v 0.5039 0.6639 -0.1257 +v 0.5413 0.5168 0.0092 +v 0.5031 0.6686 -0.1125 +v 0.5327 0.5174 0.0054 +v 0.4791 0.6807 -0.1241 +v 0.7373 0.6903 0.1852 +v 0.7417 0.6977 0.2756 +v 0.5128 0.6674 -0.0998 +v 0.7229 0.6814 0.1002 +v 0.7119 0.7257 0.1136 +v 0.5199 0.6768 -0.0623 +v 0.5147 0.6813 -0.0562 +v 0.6730 0.5500 0.0303 +v 0.5024 0.6834 -0.0634 +v 0.7196 0.7647 0.2546 +v 0.6510 0.5129 0.0235 +v 0.2529 0.3140 0.0303 +v 0.5906 0.4839 -0.0078 +v 0.5462 0.6605 -0.0508 +v 0.4910 0.7798 -0.0353 +v 0.4916 0.7787 -0.0363 +v 0.6419 0.5178 0.0164 +# 468 vertices + + +vt 0.0147 0.4668 0.0000 +vt 0.1049 0.4716 0.0000 +vt 0.1292 0.5313 0.0000 +vt 0.5005 0.2458 0.0000 +vt 0.5005 0.2570 0.0000 +vt 0.4745 0.2628 0.0000 +vt 0.3859 0.4818 0.0000 +vt 0.3646 0.4669 0.0000 +vt 0.3693 0.4471 0.0000 +vt 0.4759 0.2479 0.0000 +vt 0.4423 0.2555 0.0000 +vt 0.4120 0.4846 0.0000 +vt 0.3932 0.4639 0.0000 +vt 0.4003 0.4442 0.0000 +vt 0.2789 0.6680 0.0000 +vt 0.3509 0.6923 0.0000 +vt 0.3233 0.7432 0.0000 +vt 0.5005 0.0338 0.0000 +vt 0.4441 0.0397 0.0000 +vt 0.4312 0.0048 0.0000 +vt 0.2866 0.4184 0.0000 +vt 0.2814 0.3609 0.0000 +vt 0.3366 0.3971 0.0000 +vt 0.4479 0.2441 0.0000 +vt 0.4187 0.2424 0.0000 +vt 0.5013 0.6285 0.0000 +vt 0.5009 0.7040 0.0000 +vt 0.4227 0.7019 0.0000 +vt 0.4367 0.3599 0.0000 +vt 0.4546 0.3734 0.0000 +vt 0.4474 0.3880 0.0000 +vt 0.4127 0.1154 0.0000 +vt 0.3776 0.1397 0.0000 +vt 0.3570 0.1118 0.0000 +vt 0.4245 0.2358 0.0000 +vt 0.3990 0.2257 0.0000 +vt 0.4291 0.2176 0.0000 +vt 0.4278 0.2257 0.0000 +vt 0.4085 0.2183 0.0000 +vt 0.3920 0.2671 0.0000 +vt 0.3702 0.2432 0.0000 +vt 0.3340 0.4539 0.0000 +vt 0.2997 0.4488 0.0000 +vt 0.3483 0.1726 0.0000 +vt 0.3277 0.2091 0.0000 +vt 0.2881 0.2020 0.0000 +vt 0.4647 0.1244 0.0000 +vt 0.5005 0.1223 0.0000 +vt 0.5005 0.1584 0.0000 +vt 0.3882 0.2060 0.0000 +vt 0.3842 0.2055 0.0000 +vt 0.4009 0.1949 0.0000 +vt 0.3240 0.5332 0.0000 +vt 0.3086 0.5596 0.0000 +vt 0.2893 0.5442 0.0000 +vt 0.3901 0.5544 0.0000 +vt 0.3855 0.5335 0.0000 +vt 0.3961 0.5202 0.0000 +vt 0.4023 0.1612 0.0000 +vt 0.2419 0.1475 0.0000 +vt 0.2356 0.2274 0.0000 +vt 0.3833 0.3293 0.0000 +vt 0.4165 0.2829 0.0000 +vt 0.4238 0.3222 0.0000 +vt 0.1094 0.6010 0.0000 +vt 0.1699 0.5849 0.0000 +vt 0.2225 0.6315 0.0000 +vt 0.4860 0.4115 0.0000 +vt 0.4924 0.3854 0.0000 +vt 0.5012 0.3858 0.0000 +vt 0.3136 0.4853 0.0000 +vt 0.3135 0.4704 0.0000 +vt 0.3372 0.4740 0.0000 +vt 0.4066 0.2006 0.0000 +vt 0.4228 0.1832 0.0000 +vt 0.3239 0.3285 0.0000 +vt 0.2580 0.2993 0.0000 +vt 0.4569 0.0982 0.0000 +vt 0.5005 0.0934 0.0000 +vt 0.4319 0.1411 0.0000 +vt 0.4280 0.1927 0.0000 +vt 0.4470 0.1698 0.0000 +vt 0.4744 0.1790 0.0000 +vt 0.4737 0.1615 0.0000 +vt 0.3593 0.2991 0.0000 +vt 0.3583 0.3638 0.0000 +vt 0.3901 0.0568 0.0000 +vt 0.4604 0.5378 0.0000 +vt 0.4215 0.5338 0.0000 +vt 0.4193 0.5091 0.0000 +vt 0.3461 0.5423 0.0000 +vt 0.3661 0.5430 0.0000 +vt 0.3662 0.5686 0.0000 +vt 0.2731 0.5238 0.0000 +vt 0.2948 0.5106 0.0000 +vt 0.3067 0.5212 0.0000 +vt 0.4582 0.4314 0.0000 +vt 0.4820 0.4394 0.0000 +vt 0.4781 0.4654 0.0000 +vt 0.1687 0.6591 0.0000 +vt 0.5006 0.5393 0.0000 +vt 0.5005 0.5826 0.0000 +vt 0.2482 0.4258 0.0000 +vt 0.2699 0.4542 0.0000 +vt 0.2515 0.4650 0.0000 +vt 0.4436 0.5938 0.0000 +vt 0.4655 0.3097 0.0000 +vt 0.4596 0.3179 0.0000 +vt 0.4055 0.4116 0.0000 +vt 0.3746 0.4209 0.0000 +vt 0.4472 0.3421 0.0000 +vt 0.4638 0.3541 0.0000 +vt 0.4621 0.3644 0.0000 +vt 0.3851 0.5111 0.0000 +vt 0.3696 0.5043 0.0000 +vt 0.3786 0.4937 0.0000 +vt 0.4170 0.3941 0.0000 +vt 0.4310 0.3714 0.0000 +vt 0.1987 0.1072 0.0000 +vt 0.2659 0.0727 0.0000 +vt 0.4255 0.4356 0.0000 +vt 0.3309 0.5828 0.0000 +vt 0.3224 0.6075 0.0000 +vt 0.2824 0.5897 0.0000 +vt 0.4691 0.4044 0.0000 +vt 0.3374 0.0828 0.0000 +vt 0.3767 0.1817 0.0000 +vt 0.3352 0.4294 0.0000 +vt 0.2436 0.4922 0.0000 +vt 0.2667 0.4989 0.0000 +vt 0.2640 0.6037 0.0000 +vt 0.4861 0.3510 0.0000 +vt 0.4776 0.3328 0.0000 +vt 0.4828 0.3273 0.0000 +vt 0.2509 0.5633 0.0000 +vt 0.2244 0.5712 0.0000 +vt 0.1957 0.5278 0.0000 +vt 0.3952 0.2075 0.0000 +vt 0.3920 0.2069 0.0000 +vt 0.4106 0.2053 0.0000 +vt 0.1759 0.4752 0.0000 +vt 0.1009 0.4117 0.0000 +vt 0.1954 0.3660 0.0000 +vt 0.2214 0.4448 0.0000 +vt 0.4894 0.3650 0.0000 +vt 0.4963 0.3512 0.0000 +vt 0.5013 0.3506 0.0000 +vt 0.3407 0.2632 0.0000 +vt 0.3509 0.4949 0.0000 +vt 0.3596 0.4824 0.0000 +vt 0.4679 0.2897 0.0000 +vt 0.4512 0.0662 0.0000 +vt 0.3857 0.3856 0.0000 +vt 0.3562 0.2113 0.0000 +vt 0.4558 0.3242 0.0000 +vt 0.2113 0.4830 0.0000 +vt 0.2544 0.5237 0.0000 +vt 0.3366 0.5693 0.0000 +vt 0.3182 0.1465 0.0000 +vt 0.2735 0.5527 0.0000 +vt 0.1012 0.3494 0.0000 +vt 0.1847 0.4235 0.0000 +vt 0.4508 0.2318 0.0000 +vt 0.4757 0.2315 0.0000 +vt 0.4010 0.3544 0.0000 +vt 0.4301 0.3460 0.0000 +vt 0.4367 0.3271 0.0000 +vt 0.4212 0.3580 0.0000 +vt 0.3021 0.2818 0.0000 +vt 0.4032 0.2219 0.0000 +vt 0.2912 0.1118 0.0000 +vt 0.3179 0.0469 0.0000 +vt 0.3723 0.0264 0.0000 +vt 0.3117 0.6281 0.0000 +vt 0.3711 0.6357 0.0000 +vt 0.4738 0.4975 0.0000 +vt 0.5008 0.5007 0.0000 +vt 0.1975 0.3082 0.0000 +vt 0.3746 0.6135 0.0000 +vt 0.4366 0.6327 0.0000 +vt 0.4299 0.2024 0.0000 +vt 0.4496 0.1861 0.0000 +vt 0.0053 0.3348 0.0000 +vt 0.5005 0.1954 0.0000 +vt 0.4749 0.1968 0.0000 +vt 0.5005 0.2115 0.0000 +vt 0.4768 0.2107 0.0000 +vt 0.3319 0.4878 0.0000 +vt 0.4328 0.2102 0.0000 +vt 0.4508 0.2000 0.0000 +vt 0.4135 0.2110 0.0000 +vt 0.1895 0.1824 0.0000 +vt 0.1298 0.1429 0.0000 +vt 0.1384 0.2290 0.0000 +vt 0.0685 0.1945 0.0000 +vt 0.4418 0.3514 0.0000 +vt 0.4494 0.2171 0.0000 +vt 0.5009 0.4400 0.0000 +vt 0.5005 0.0619 0.0000 +vt 0.4742 0.2157 0.0000 +vt 0.3008 0.4876 0.0000 +vt 0.2923 0.4722 0.0000 +vt 0.0005 0.4015 0.0000 +vt 0.4068 0.7707 0.0000 +vt 0.4363 0.3405 0.0000 +vt 0.4123 0.2121 0.0000 +vt 0.3686 0.5816 0.0000 +vt 0.4912 0.3214 0.0000 +vt 0.4097 0.5625 0.0000 +vt 0.5005 0.4679 0.0000 +vt 0.2791 0.4819 0.0000 +vt 0.2919 0.4918 0.0000 +vt 0.2827 0.4994 0.0000 +vt 0.4738 0.3832 0.0000 +vt 0.4791 0.3668 0.0000 +vt 0.4334 0.5056 0.0000 +vt 0.0543 0.5378 0.0000 +vt 0.4456 0.4851 0.0000 +vt 0.4515 0.4542 0.0000 +vt 0.5005 0.3015 0.0000 +vt 0.4916 0.3521 0.0000 +vt 0.5008 0.2886 0.0000 +vt 0.5005 0.2309 0.0000 +vt 0.5005 0.2127 0.0000 +vt 0.4341 0.4127 0.0000 +vt 0.3949 0.5126 0.0000 +vt 0.3922 0.5039 0.0000 +vt 0.4020 0.5117 0.0000 +vt 0.4750 0.3572 0.0000 +vt 0.4057 0.5296 0.0000 +vt 0.4019 0.0857 0.0000 +vt 0.4541 0.2102 0.0000 +vt 0.0273 0.2648 0.0000 +vt 0.1148 0.2863 0.0000 +vt 0.5011 0.3651 0.0000 +vt 0.1987 0.2586 0.0000 +vt 0.4424 0.3354 0.0000 +vt 0.5008 0.3208 0.0000 +vt 0.4437 0.3275 0.0000 +vt 0.2981 0.5717 0.0000 +vt 0.4023 0.4956 0.0000 +vt 0.4203 0.4658 0.0000 +vt 0.2287 0.5259 0.0000 +vt 0.9848 0.4692 0.0000 +vt 0.9459 0.5412 0.0000 +vt 0.8720 0.5338 0.0000 +vt 0.5265 0.2472 0.0000 +vt 0.5278 0.2623 0.0000 +vt 0.6153 0.4824 0.0000 +vt 0.6078 0.4648 0.0000 +vt 0.6324 0.4475 0.0000 +vt 0.5545 0.2426 0.0000 +vt 0.5596 0.2542 0.0000 +vt 0.5894 0.4851 0.0000 +vt 0.5805 0.4662 0.0000 +vt 0.6005 0.4447 0.0000 +vt 0.5981 0.4959 0.0000 +vt 0.7226 0.6706 0.0000 +vt 0.7602 0.7091 0.0000 +vt 0.6771 0.7445 0.0000 +vt 0.5005 0.0005 0.0000 +vt 0.5712 0.0054 0.0000 +vt 0.7164 0.4194 0.0000 +vt 0.6676 0.4301 0.0000 +vt 0.6652 0.3982 0.0000 +vt 0.5782 0.2337 0.0000 +vt 0.5835 0.2407 0.0000 +vt 0.5670 0.6338 0.0000 +vt 0.5793 0.7023 0.0000 +vt 0.5645 0.3606 0.0000 +vt 0.5700 0.3722 0.0000 +vt 0.5539 0.3888 0.0000 +vt 0.5906 0.1168 0.0000 +vt 0.6014 0.0873 0.0000 +vt 0.6464 0.1140 0.0000 +vt 0.5984 0.2198 0.0000 +vt 0.6026 0.2235 0.0000 +vt 0.5728 0.2157 0.0000 +vt 0.5891 0.2097 0.0000 +vt 0.5936 0.2159 0.0000 +vt 0.6318 0.2428 0.0000 +vt 0.6677 0.4541 0.0000 +vt 0.6550 0.1736 0.0000 +vt 0.6842 0.1482 0.0000 +vt 0.7142 0.2035 0.0000 +vt 0.5379 0.1252 0.0000 +vt 0.5294 0.1616 0.0000 +vt 0.6140 0.2039 0.0000 +vt 0.5958 0.1986 0.0000 +vt 0.6018 0.1939 0.0000 +vt 0.6771 0.5351 0.0000 +vt 0.6938 0.5232 0.0000 +vt 0.7137 0.5456 0.0000 +vt 0.6110 0.5558 0.0000 +vt 0.5943 0.5303 0.0000 +vt 0.6034 0.5215 0.0000 +vt 0.6001 0.1616 0.0000 +vt 0.5710 0.1421 0.0000 +vt 0.7597 0.1494 0.0000 +vt 0.8115 0.1846 0.0000 +vt 0.7662 0.2292 0.0000 +vt 0.6177 0.3301 0.0000 +vt 0.5999 0.3550 0.0000 +vt 0.5771 0.3224 0.0000 +vt 0.8905 0.6045 0.0000 +vt 0.8310 0.6625 0.0000 +vt 0.7787 0.6346 0.0000 +vt 0.5151 0.4121 0.0000 +vt 0.5009 0.4119 0.0000 +vt 0.6876 0.4855 0.0000 +vt 0.6697 0.4878 0.0000 +vt 0.6640 0.4736 0.0000 +vt 0.5748 0.1915 0.0000 +vt 0.5804 0.1824 0.0000 +vt 0.6785 0.3296 0.0000 +vt 0.7003 0.2837 0.0000 +vt 0.7442 0.3013 0.0000 +vt 0.5459 0.0983 0.0000 +vt 0.5564 0.1701 0.0000 +vt 0.5539 0.1850 0.0000 +vt 0.5284 0.1787 0.0000 +vt 0.5005 0.1772 0.0000 +vt 0.6430 0.3002 0.0000 +vt 0.6430 0.3646 0.0000 +vt 0.6303 0.0280 0.0000 +vt 0.6132 0.0590 0.0000 +vt 0.6097 0.2674 0.0000 +vt 0.5849 0.2832 0.0000 +vt 0.5402 0.5378 0.0000 +vt 0.5678 0.5055 0.0000 +vt 0.5815 0.5092 0.0000 +vt 0.6558 0.5438 0.0000 +vt 0.6657 0.5712 0.0000 +vt 0.6354 0.5697 0.0000 +vt 0.7059 0.5124 0.0000 +vt 0.5430 0.4322 0.0000 +vt 0.5497 0.4544 0.0000 +vt 0.5233 0.4656 0.0000 +vt 0.5587 0.5950 0.0000 +vt 0.7543 0.4271 0.0000 +vt 0.7807 0.4461 0.0000 +vt 0.7504 0.4667 0.0000 +vt 0.5788 0.5343 0.0000 +vt 0.5917 0.5639 0.0000 +vt 0.5647 0.3278 0.0000 +vt 0.5418 0.3174 0.0000 +vt 0.5956 0.4123 0.0000 +vt 0.6156 0.3864 0.0000 +vt 0.6264 0.4223 0.0000 +vt 0.5542 0.3419 0.0000 +vt 0.5591 0.3514 0.0000 +vt 0.5393 0.3648 0.0000 +vt 0.6157 0.5115 0.0000 +vt 0.6086 0.5039 0.0000 +vt 0.6221 0.4943 0.0000 +vt 0.5841 0.3948 0.0000 +vt 0.5672 0.4138 0.0000 +vt 0.7110 0.1141 0.0000 +vt 0.7358 0.0748 0.0000 +vt 0.5756 0.4364 0.0000 +vt 0.6724 0.5841 0.0000 +vt 0.7053 0.5733 0.0000 +vt 0.7220 0.5927 0.0000 +vt 0.5098 0.3851 0.0000 +vt 0.5277 0.3835 0.0000 +vt 0.5323 0.4048 0.0000 +vt 0.5945 0.7713 0.0000 +vt 0.6251 0.1815 0.0000 +vt 0.6365 0.4674 0.0000 +vt 0.7583 0.4933 0.0000 +vt 0.7484 0.5253 0.0000 +vt 0.7302 0.5250 0.0000 +vt 0.7398 0.6069 0.0000 +vt 0.6925 0.6304 0.0000 +vt 0.6819 0.6101 0.0000 +vt 0.5160 0.3506 0.0000 +vt 0.5102 0.3521 0.0000 +vt 0.5188 0.3269 0.0000 +vt 0.7529 0.5667 0.0000 +vt 0.7737 0.5282 0.0000 +vt 0.8066 0.5304 0.0000 +vt 0.6068 0.2054 0.0000 +vt 0.5889 0.2094 0.0000 +vt 0.5914 0.2039 0.0000 +vt 0.7790 0.5747 0.0000 +vt 0.8264 0.4776 0.0000 +vt 0.8176 0.4259 0.0000 +vt 0.8998 0.4138 0.0000 +vt 0.8059 0.3678 0.0000 +vt 0.5123 0.3651 0.0000 +vt 0.5195 0.4396 0.0000 +vt 0.6613 0.2639 0.0000 +vt 0.6307 0.5044 0.0000 +vt 0.6418 0.4822 0.0000 +vt 0.5337 0.2895 0.0000 +vt 0.5524 0.0668 0.0000 +vt 0.6458 0.2115 0.0000 +vt 0.5245 0.3325 0.0000 +vt 0.6141 0.5347 0.0000 +vt 0.7909 0.4849 0.0000 +vt 0.6941 0.5613 0.0000 +vt 0.6256 0.1415 0.0000 +vt 0.6096 0.2049 0.0000 +vt 0.9000 0.3524 0.0000 +vt 0.5515 0.2303 0.0000 +vt 0.5709 0.3469 0.0000 +vt 0.5645 0.3412 0.0000 +vt 0.5747 0.2240 0.0000 +vt 0.6746 0.2107 0.0000 +vt 0.6652 0.0847 0.0000 +vt 0.6511 0.6939 0.0000 +vt 0.5274 0.4979 0.0000 +vt 0.7207 0.3628 0.0000 +vt 0.5729 0.2018 0.0000 +vt 0.6289 0.6150 0.0000 +vt 0.6339 0.6380 0.0000 +vt 0.5520 0.1991 0.0000 +vt 0.9949 0.3369 0.0000 +vt 0.9995 0.4038 0.0000 +vt 0.5281 0.1971 0.0000 +vt 0.6494 0.4952 0.0000 +vt 0.5698 0.2093 0.0000 +vt 0.5491 0.2099 0.0000 +vt 0.8023 0.1093 0.0000 +vt 0.8624 0.2316 0.0000 +vt 0.8703 0.1449 0.0000 +vt 0.5467 0.3737 0.0000 +vt 0.5529 0.2158 0.0000 +vt 0.6173 0.2034 0.0000 +vt 0.5588 0.0402 0.0000 +vt 0.5267 0.2312 0.0000 +vt 0.7295 0.5547 0.0000 +vt 0.6883 0.4705 0.0000 +vt 0.7097 0.4730 0.0000 +vt 0.7023 0.4497 0.0000 +vt 0.8959 0.4739 0.0000 +vt 0.5005 0.7724 0.0000 +vt 0.6340 0.5832 0.0000 +vt 0.5103 0.3214 0.0000 +vt 0.7183 0.5004 0.0000 +vt 0.7223 0.4825 0.0000 +vt 0.7349 0.4997 0.0000 +vt 0.5555 0.4858 0.0000 +vt 0.8313 0.5881 0.0000 +vt 0.6843 0.0486 0.0000 +vt 0.5357 0.3096 0.0000 +vt 0.5225 0.3673 0.0000 +vt 0.6052 0.5128 0.0000 +vt 0.5262 0.3575 0.0000 +vt 0.5981 0.5120 0.0000 +vt 0.5059 0.3513 0.0000 +vt 0.8860 0.2886 0.0000 +vt 0.9734 0.2673 0.0000 +vt 0.5380 0.3550 0.0000 +vt 0.8040 0.3108 0.0000 +vt 0.8029 0.2613 0.0000 +vt 0.5581 0.3352 0.0000 +vt 0.5573 0.3283 0.0000 +vt 0.7323 0.4549 0.0000 +vt 0.5458 0.3240 0.0000 +vt 0.9322 0.1972 0.0000 +vt 0.7099 0.4918 0.0000 +vt 0.2399 0.7066 0.0000 +vt 0.6343 0.5445 0.0000 +vt 0.5798 0.3590 0.0000 +vt 0.5256 0.2097 0.0000 +vt 0.5282 0.2152 0.0000 +vt 0.7007 0.4875 0.0000 +# 468 texture coords + + +vn -0.9892 0.0918 -0.1146 +vn -0.9788 0.0236 -0.2033 +vn -0.9677 -0.0121 -0.2518 +vn -0.0286 0.4641 -0.8853 +vn -0.0210 0.1059 -0.9942 +vn -0.2963 0.0263 -0.9547 +vn -0.2656 -0.3737 -0.8887 +vn -0.1333 -0.1062 -0.9854 +vn -0.2982 -0.3067 -0.9039 +vn -0.2701 0.4062 -0.8730 +vn -0.5118 0.1804 -0.8400 +vn -0.6858 -0.4508 -0.5714 +vn -0.4596 -0.4367 -0.7734 +vn -0.6024 -0.3459 -0.7194 +vn -0.6700 -0.2574 -0.6963 +vn -0.3874 -0.2160 -0.8962 +vn -0.4873 -0.2184 -0.8455 +vn -0.0187 0.7636 -0.6454 +vn -0.3895 0.6894 -0.6107 +vn -0.3730 0.8476 -0.3773 +vn -0.4425 -0.2135 -0.8710 +vn -0.6390 0.0497 -0.7676 +vn -0.3241 -0.1838 -0.9280 +vn -0.4361 0.4943 -0.7520 +vn -0.5509 0.4800 -0.6827 +vn -0.0096 0.1041 -0.9945 +vn -0.0117 -0.1221 -0.9924 +vn -0.2092 -0.1327 -0.9688 +vn -0.9011 0.2674 -0.3415 +vn -0.8776 0.0591 -0.4757 +vn -0.8804 -0.3287 -0.3418 +vn -0.5055 0.2486 -0.8262 +vn -0.5902 0.2855 -0.7551 +vn -0.6930 0.3322 -0.6398 +vn -0.4684 0.6694 -0.5766 +vn -0.4272 0.7368 -0.5240 +vn -0.2852 0.8727 -0.3964 +vn -0.3535 0.8216 -0.4473 +vn -0.3118 0.8767 -0.3662 +vn -0.5250 0.1467 -0.8384 +vn -0.4721 0.4437 -0.7617 +vn -0.2451 -0.0267 -0.9691 +vn -0.4187 -0.1407 -0.8972 +vn -0.5714 0.2908 -0.7675 +vn -0.5276 0.3879 -0.7558 +vn -0.7228 0.4014 -0.5625 +vn -0.1836 0.4449 -0.8765 +vn -0.0125 0.4693 -0.8829 +vn -0.0217 0.5490 -0.8355 +vn -0.7483 0.2841 -0.5994 +vn -0.4508 0.3894 -0.8032 +vn -0.7218 -0.1978 -0.6632 +vn -0.2589 0.4773 -0.8397 +vn -0.1985 0.5505 -0.8109 +vn -0.3127 0.5807 -0.7516 +vn -0.1325 0.5499 -0.8246 +vn 0.0988 0.3107 -0.9454 +vn -0.0383 0.4255 -0.9042 +vn -0.5889 0.2725 -0.7609 +vn -0.8103 0.4772 -0.3402 +vn -0.8348 0.3692 -0.4084 +vn -0.3030 -0.0161 -0.9529 +vn -0.4987 -0.0940 -0.8617 +vn -0.6857 0.2014 -0.6994 +vn -0.9601 -0.0063 -0.2796 +vn -0.9401 -0.0814 -0.3311 +vn -0.8443 -0.2348 -0.4818 +vn -0.5192 -0.4575 -0.7219 +vn -0.4560 -0.0053 -0.8899 +vn -0.0145 0.0191 -0.9997 +vn -0.4007 -0.1577 -0.9025 +vn -0.3961 -0.0224 -0.9179 +vn -0.1931 0.0337 -0.9806 +vn -0.6352 -0.3880 -0.6678 +vn -0.6957 0.1472 -0.7031 +vn -0.4450 0.1127 -0.8884 +vn -0.7920 0.2538 -0.5553 +vn -0.2588 0.1393 -0.9558 +vn -0.0160 0.0757 -0.9970 +vn -0.4640 0.3737 -0.8031 +vn -0.5965 -0.2402 -0.7659 +vn -0.5234 0.3510 -0.7764 +vn -0.2373 0.0020 -0.9714 +vn -0.2813 0.4791 -0.8315 +vn -0.3584 0.0892 -0.9293 +vn -0.2542 0.0002 -0.9671 +vn -0.6701 0.5630 -0.4837 +vn -0.7034 0.1121 -0.7019 +vn -0.6507 0.4083 -0.6402 +vn -0.7793 -0.1925 -0.5964 +vn -0.1515 0.3979 -0.9048 +vn -0.0209 0.3518 -0.9359 +vn -0.1058 0.5639 -0.8190 +vn -0.3450 0.6540 -0.6732 +vn -0.3752 0.7249 -0.5777 +vn -0.3356 0.6076 -0.7198 +vn -0.8198 -0.4081 -0.4018 +vn -0.6040 -0.5115 -0.6112 +vn -0.6003 -0.4769 -0.6420 +vn -0.8971 -0.1474 -0.4166 +vn -0.0088 -0.1756 -0.9844 +vn -0.0130 0.2566 -0.9664 +vn -0.6727 -0.1461 -0.7253 +vn -0.5253 -0.1978 -0.8276 +vn -0.5550 -0.1543 -0.8174 +vn -0.2962 0.5043 -0.8111 +vn -0.5151 0.3789 -0.7689 +vn -0.6769 0.4352 -0.5936 +vn -0.7119 -0.1376 -0.6887 +vn -0.3869 -0.2729 -0.8808 +vn -0.2593 0.9100 -0.3235 +vn -0.4232 0.8725 -0.2441 +vn -0.6388 0.6348 -0.4346 +vn 0.0075 -0.5272 -0.8497 +vn 0.1431 -0.3278 -0.9338 +vn 0.0417 -0.2968 -0.9540 +vn -0.9190 -0.2914 -0.2656 +vn -0.9525 -0.1975 -0.2320 +vn -0.8218 0.5259 -0.2193 +vn -0.7717 0.5717 -0.2788 +vn -0.8407 -0.2471 -0.4819 +vn -0.1589 0.6204 -0.7680 +vn -0.3844 0.3934 -0.8351 +vn -0.5135 0.2291 -0.8270 +vn -0.7775 -0.3931 -0.4910 +vn -0.7590 0.4870 -0.4321 +vn -0.5333 0.0772 -0.8424 +vn -0.2512 -0.2327 -0.9396 +vn -0.5037 0.2809 -0.8169 +vn -0.3684 0.3409 -0.8649 +vn -0.7436 -0.0832 -0.6634 +vn -0.6117 0.7847 -0.1002 +vn -0.5291 0.8080 -0.2592 +vn -0.4508 0.8443 -0.2898 +vn -0.6923 0.3110 -0.6511 +vn -0.8890 -0.0214 -0.4573 +vn -0.8997 0.1327 -0.4158 +vn -0.2615 0.0617 -0.9632 +vn -0.7042 -0.3851 -0.5965 +vn -0.4049 -0.7183 -0.5658 +vn -0.8981 0.0608 -0.4355 +vn -0.9788 0.1245 -0.1626 +vn -0.9079 0.1364 -0.3963 +vn -0.7298 -0.0858 -0.6783 +vn -0.4109 0.5683 -0.7129 +vn -0.2760 0.8715 -0.4054 +vn -0.0052 0.8916 -0.4528 +vn -0.4766 0.3068 -0.8238 +vn 0.0050 -0.1775 -0.9841 +vn -0.0091 -0.0562 -0.9984 +vn -0.3366 0.0198 -0.9414 +vn -0.3670 0.2717 -0.8897 +vn -0.3339 0.0046 -0.9426 +vn -0.3391 0.4495 -0.8264 +vn -0.6108 0.5190 -0.5979 +vn -0.7075 0.1706 -0.6858 +vn -0.4370 0.5756 -0.6911 +vn -0.1373 0.5563 -0.8196 +vn -0.6839 0.4104 -0.6032 +vn -0.4112 0.5547 -0.7234 +vn -0.9719 0.1950 -0.1316 +vn -0.8965 0.0314 -0.4419 +vn -0.3061 0.7640 -0.5679 +vn -0.2095 0.7295 -0.6511 +vn -0.6765 0.0404 -0.7353 +vn -0.7748 0.5551 -0.3026 +vn -0.3352 0.8062 -0.4875 +vn -0.9828 0.0737 -0.1690 +vn -0.6294 0.2746 -0.7270 +vn -0.4010 0.7990 -0.4481 +vn -0.7680 0.5065 -0.3919 +vn -0.7313 0.6102 -0.3048 +vn -0.6386 0.7024 -0.3143 +vn -0.5403 -0.0661 -0.8389 +vn -0.2972 0.0398 -0.9540 +vn -0.6776 -0.4136 -0.6081 +vn -0.0027 -0.5203 -0.8540 +vn -0.9184 0.2515 -0.3056 +vn -0.2748 0.5707 -0.7738 +vn -0.1584 0.1286 -0.9790 +vn -0.4616 -0.5618 -0.6866 +vn -0.4293 -0.0927 -0.8984 +vn -0.9793 0.1926 -0.0624 +vn -0.0161 -0.1523 -0.9882 +vn -0.2259 -0.2227 -0.9484 +vn -0.0197 -0.0720 -0.9972 +vn -0.2632 -0.1251 -0.9566 +vn -0.2093 -0.1177 -0.9707 +vn -0.4462 -0.5951 -0.6684 +vn -0.3734 -0.3688 -0.8512 +vn -0.4127 -0.7924 -0.4493 +vn -0.8775 0.4155 -0.2396 +vn -0.8941 0.4319 -0.1185 +vn -0.9429 0.3025 -0.1392 +vn -0.9468 0.3122 -0.0776 +vn -0.4967 0.7780 -0.3847 +vn -0.2129 0.8951 -0.3917 +vn -0.0010 -0.6457 -0.7636 +vn -0.0191 0.3220 -0.9466 +vn -0.2007 0.8540 -0.4801 +vn -0.5261 -0.2296 -0.8189 +vn -0.5469 -0.1438 -0.8248 +vn -0.9882 0.1379 -0.0665 +vn -0.2607 -0.1418 -0.9549 +vn -0.3010 0.8206 -0.4858 +vn -0.2486 0.9237 -0.2915 +vn -0.1986 0.7334 -0.6502 +vn -0.2171 0.9455 -0.2426 +vn -0.3870 0.6895 -0.6122 +vn -0.0087 -0.5839 -0.8117 +vn -0.5436 -0.1897 -0.8176 +vn -0.5570 -0.2589 -0.7891 +vn -0.4501 0.2685 -0.8516 +vn -0.7925 0.0362 -0.6087 +vn -0.6696 0.5211 -0.5292 +vn -0.8579 -0.2632 -0.4412 +vn -0.9774 0.0665 -0.2005 +vn -0.8059 -0.4189 -0.4185 +vn -0.8334 -0.3312 -0.4425 +vn -0.0113 0.7507 -0.6605 +vn -0.5000 0.8023 -0.3261 +vn -0.0179 0.1168 -0.9930 +vn -0.0280 0.7348 -0.6777 +vn -0.0341 0.8515 -0.5232 +vn -0.8728 -0.3807 -0.3053 +vn -0.2925 -0.1250 -0.9481 +vn -0.2521 -0.4913 -0.8337 +vn -0.5752 -0.1476 -0.8046 +vn -0.5558 0.7877 -0.2655 +vn -0.3244 0.4596 -0.8268 +vn -0.6118 0.2479 -0.7511 +vn -0.3883 -0.3420 -0.8557 +vn -0.9704 0.2327 -0.0645 +vn -0.9662 0.2260 -0.1243 +vn -0.0165 0.5612 -0.8275 +vn -0.8997 0.3056 -0.3117 +vn -0.1538 0.8423 -0.5165 +vn 0.0106 0.9761 -0.2172 +vn -0.4197 0.4256 -0.8017 +vn -0.2580 0.5206 -0.8139 +vn -0.5099 -0.4374 -0.7407 +vn -0.7786 -0.4123 -0.4731 +vn -0.6680 0.4185 -0.6154 +vn 0.9885 0.0946 -0.1177 +vn 0.9766 0.0763 -0.2009 +vn 0.9707 -0.0059 -0.2403 +vn 0.2175 0.4167 -0.8827 +vn 0.2655 0.0332 -0.9635 +vn 0.2465 -0.3758 -0.8933 +vn 0.4508 -0.4321 -0.7811 +vn 0.2787 -0.3017 -0.9118 +vn 0.3870 0.4936 -0.7788 +vn 0.4777 0.1827 -0.8593 +vn 0.6807 -0.4529 -0.5758 +vn 0.7749 -0.3960 -0.4927 +vn 0.5928 -0.3359 -0.7320 +vn 0.5041 -0.4457 -0.7397 +vn 0.6609 -0.2685 -0.7009 +vn 0.7711 -0.1906 -0.6075 +vn 0.4693 -0.2150 -0.8565 +vn -0.0176 0.9138 -0.4057 +vn 0.3385 0.8619 -0.3777 +vn 0.4241 -0.2022 -0.8827 +vn 0.2284 -0.2246 -0.9473 +vn 0.3009 -0.1708 -0.9382 +vn 0.4152 0.6914 -0.5913 +vn 0.5263 0.4569 -0.7171 +vn 0.1372 0.1315 -0.9818 +vn 0.1889 -0.1299 -0.9734 +vn 0.8941 0.2902 -0.3410 +vn 0.9565 -0.1796 -0.2300 +vn 0.8827 -0.3064 -0.3563 +vn 0.4749 0.2725 -0.8368 +vn 0.5803 0.2684 -0.7689 +vn 0.6698 0.3602 -0.6493 +vn 0.3502 0.8087 -0.4726 +vn 0.3789 0.7560 -0.5337 +vn 0.1939 0.9029 -0.3835 +vn 0.0992 0.9694 -0.2244 +vn 0.2482 0.8870 -0.3894 +vn 0.4589 0.4349 -0.7748 +vn 0.2199 -0.0208 -0.9753 +vn 0.5447 0.3217 -0.7745 +vn 0.6608 0.4456 -0.6039 +vn 0.7042 0.4225 -0.5706 +vn 0.1420 0.4548 -0.8792 +vn 0.2331 0.5063 -0.8303 +vn 0.8500 -0.0556 -0.5238 +vn 0.6186 -0.3893 -0.6824 +vn 0.7050 -0.2003 -0.6803 +vn 0.2278 0.4733 -0.8510 +vn 0.3290 0.5971 -0.7316 +vn 0.2896 0.5777 -0.7632 +vn 0.1057 0.5527 -0.8267 +vn 0.2923 0.4695 -0.8331 +vn 0.0250 0.4179 -0.9081 +vn 0.5611 0.3112 -0.7670 +vn 0.4233 0.4058 -0.8100 +vn 0.7948 0.5049 -0.3366 +vn 0.8680 0.4384 -0.2332 +vn 0.8266 0.3904 -0.4053 +vn 0.2732 -0.0165 -0.9618 +vn 0.6635 0.0658 -0.7453 +vn 0.6643 0.2138 -0.7162 +vn 0.9600 -0.0003 -0.2800 +vn 0.8960 -0.1414 -0.4210 +vn 0.8452 -0.2504 -0.4722 +vn 0.5089 -0.4481 -0.7350 +vn -0.0089 -0.4314 -0.9021 +vn 0.3708 -0.1626 -0.9144 +vn 0.1925 -0.1126 -0.9748 +vn 0.1658 0.0472 -0.9850 +vn 0.5831 -0.2210 -0.7818 +vn 0.6667 0.1757 -0.7243 +vn 0.4231 0.1187 -0.8983 +vn 0.6085 0.2868 -0.7400 +vn 0.7769 0.2723 -0.5677 +vn 0.2238 0.1445 -0.9639 +vn 0.4823 0.3914 -0.7837 +vn 0.4059 -0.0703 -0.9112 +vn 0.1984 0.0143 -0.9800 +vn -0.0156 0.0695 -0.9975 +vn 0.3273 0.0921 -0.9404 +vn 0.2286 0.0054 -0.9735 +vn 0.6102 0.7222 -0.3257 +vn 0.6443 0.5803 -0.4981 +vn 0.4969 0.1416 -0.8562 +vn 0.4749 -0.0910 -0.8753 +vn 0.6870 0.1214 -0.7165 +vn 0.8579 -0.2672 -0.4390 +vn 0.7796 -0.1825 -0.5992 +vn 0.1208 0.3971 -0.9098 +vn 0.1075 0.5451 -0.8314 +vn 0.0761 0.5486 -0.8326 +vn 0.3651 0.7087 -0.6037 +vn 0.8210 -0.3904 -0.4167 +vn 0.8331 -0.3228 -0.4492 +vn 0.5980 -0.4679 -0.6507 +vn 0.2695 0.5104 -0.8166 +vn 0.6652 -0.1336 -0.7347 +vn 0.7261 -0.0753 -0.6835 +vn 0.5408 -0.1514 -0.8274 +vn 0.6207 0.4346 -0.6526 +vn 0.3602 0.6969 -0.6202 +vn 0.2923 0.8174 -0.4963 +vn 0.6549 0.4616 -0.5984 +vn 0.7013 -0.1214 -0.7024 +vn 0.3127 0.0149 -0.9498 +vn 0.3730 -0.2646 -0.8893 +vn 0.2068 0.9225 -0.3261 +vn 0.4428 0.8057 -0.3933 +vn 0.6128 0.6523 -0.4461 +vn -0.0282 -0.5216 -0.8527 +vn 0.2269 -0.4823 -0.8461 +vn -0.0625 -0.2963 -0.9530 +vn 0.9255 -0.2612 -0.2742 +vn 0.8782 -0.3583 -0.3167 +vn 0.7431 0.5356 -0.4013 +vn 0.7497 0.5979 -0.2835 +vn 0.8369 -0.2377 -0.4930 +vn 0.1306 0.5947 -0.7933 +vn 0.2395 0.5098 -0.8263 +vn 0.4942 0.2256 -0.8396 +vn 0.4387 0.0211 -0.8984 +vn 0.7810 0.0588 -0.6218 +vn 0.7757 -0.3764 -0.5066 +vn 0.2367 -0.1436 -0.9609 +vn 0.5078 0.1003 -0.8556 +vn 0.1036 -0.1009 -0.9895 +vn 0.4829 0.2882 -0.8269 +vn 0.4273 0.5748 -0.6979 +vn 0.3231 0.6484 -0.6894 +vn 0.7422 -0.0986 -0.6628 +vn 0.5223 -0.0708 -0.8498 +vn 0.3597 0.3844 -0.8502 +vn 0.5795 0.8063 -0.1185 +vn 0.4603 0.8254 -0.3268 +vn 0.3691 0.8831 -0.2895 +vn 0.6861 0.3121 -0.6571 +vn 0.6473 0.4401 -0.6223 +vn 0.8993 0.1483 -0.4114 +vn 0.2468 0.0393 -0.9683 +vn 0.4702 -0.7357 -0.4875 +vn 0.4528 -0.6808 -0.5758 +vn 0.8966 -0.0343 -0.4415 +vn 0.8987 0.0843 -0.4303 +vn 0.8959 0.0466 -0.4419 +vn 0.9774 0.1340 -0.1635 +vn 0.9007 0.1575 -0.4050 +vn 0.3724 0.5882 -0.7179 +vn 0.6001 -0.5021 -0.6227 +vn 0.4579 0.3117 -0.8325 +vn -0.1567 -0.3306 -0.9307 +vn -0.0155 -0.0506 -0.9986 +vn 0.3119 0.0191 -0.9499 +vn 0.3392 0.2827 -0.8972 +vn 0.3362 0.4579 -0.8230 +vn 0.5374 0.7997 -0.2676 +vn -0.1332 0.2907 -0.9475 +vn 0.7012 0.1840 -0.6888 +vn 0.1714 0.5455 -0.8204 +vn 0.5580 0.3128 -0.7686 +vn 0.5971 0.3016 -0.7433 +vn 0.9675 0.2147 -0.1340 +vn 0.2314 0.7831 -0.5773 +vn 0.7580 0.5782 -0.3018 +vn 0.2670 0.8375 -0.4768 +vn 0.2693 0.8599 -0.4336 +vn 0.5067 0.3950 -0.7663 +vn 0.7394 0.5132 -0.4357 +vn 0.3673 -0.2156 -0.9047 +vn 0.6777 -0.3981 -0.6182 +vn 0.6185 0.0661 -0.7830 +vn 0.4711 -0.5517 -0.6882 +vn 0.2506 0.5734 -0.7800 +vn 0.2726 0.0404 -0.9613 +vn 0.3665 -0.3395 -0.8662 +vn 0.9744 0.2145 -0.0671 +vn 0.9857 0.1509 -0.0744 +vn 0.2074 -0.2071 -0.9561 +vn -0.0326 -0.1888 -0.9815 +vn 0.4509 -0.5767 -0.6812 +vn 0.3959 -0.2961 -0.8693 +vn 0.8077 0.5514 -0.2088 +vn 0.9332 0.3326 -0.1365 +vn 0.8820 0.4566 -0.1162 +vn 0.8617 0.1065 -0.4962 +vn 0.1504 0.9084 -0.3900 +vn 0.4885 0.3529 -0.7980 +vn 0.3556 0.7052 -0.6134 +vn 0.1387 0.7361 -0.6625 +vn 0.3951 0.5494 -0.7363 +vn 0.3690 -0.0160 -0.9293 +vn 0.5278 -0.1434 -0.8372 +vn 0.3953 -0.1320 -0.9090 +vn 0.9794 0.0344 -0.1991 +vn -0.0106 -0.1659 -0.9861 +vn 0.1745 0.7218 -0.6697 +vn 0.1633 0.9568 -0.2405 +vn 0.4306 0.2942 -0.8532 +vn 0.5371 -0.1872 -0.8225 +vn 0.3508 0.3438 -0.8710 +vn 0.8106 -0.3958 -0.4315 +vn 0.9431 -0.0884 -0.3207 +vn 0.7107 0.6303 -0.3125 +vn 0.4906 0.3956 -0.7764 +vn 0.6379 0.5420 -0.5471 +vn 0.2648 -0.1351 -0.9548 +vn 0.5070 0.8298 -0.2331 +vn 0.5564 -0.1294 -0.8208 +vn 0.2610 0.8806 -0.3955 +vn 0.9583 0.2570 -0.1252 +vn 0.9614 0.2663 -0.0692 +vn 0.3949 0.8811 -0.2603 +vn 0.9102 0.2754 -0.3092 +vn 0.8881 0.3375 -0.3120 +vn 0.1150 0.8695 -0.4803 +vn 0.3658 0.4631 -0.8073 +vn 0.5063 -0.1983 -0.8392 +vn 0.5772 0.5500 -0.6036 +vn 0.9361 0.3433 -0.0766 +vn 0.5392 -0.2542 -0.8029 +vn -0.7761 -0.1922 -0.6006 +vn -0.0115 0.3481 -0.9374 +vn 0.9827 0.0780 -0.1680 +vn 0.2198 -0.1358 -0.9660 +vn 0.1342 0.8481 -0.5125 +vn 0.4880 -0.2447 -0.8379 +# 468 vertex normals + +#o default +g default +#usemtl 07___Default +#s 1 +f 1/1/1 2/2/2 3/3/3 +f 4/4/4 5/5/5 6/6/6 +f 7/7/7 8/8/8 9/9/9 +f 10/10/10 6/6/6 11/11/11 +f 12/12/12 13/13/13 14/14/14 +f 7/7/7 13/13/13 12/12/12 +f 15/15/15 16/16/16 17/17/17 +f 18/18/18 19/19/19 20/20/20 +f 21/21/21 22/22/22 23/23/23 +f 24/24/24 11/11/11 25/25/25 +f 26/26/26 27/27/27 28/28/28 +f 29/29/29 30/30/30 31/31/31 +f 32/32/32 33/33/33 34/34/34 +f 35/35/35 25/25/25 36/36/36 +f 37/37/37 38/38/38 39/39/39 +f 25/25/25 40/40/40 41/41/41 +f 42/42/42 43/43/43 21/21/21 +f 44/44/44 45/45/45 46/46/46 +f 47/47/47 48/48/48 49/49/49 +f 50/50/50 51/51/51 52/52/52 +f 53/53/53 54/54/54 55/55/55 +f 56/56/56 57/57/57 58/58/58 +f 59/59/59 33/33/33 32/32/32 +f 60/60/60 46/46/46 61/61/61 +f 62/62/62 63/63/63 64/64/64 +f 65/65/65 66/66/66 67/67/67 +f 68/68/68 69/69/69 70/70/70 +f 71/71/71 72/72/72 73/73/73 +f 74/74/74 52/52/52 75/75/75 +f 76/76/76 22/22/22 77/77/77 +f 78/78/78 79/79/79 48/48/48 +f 75/75/75 59/59/59 80/80/80 +f 81/81/81 75/75/75 82/82/82 +f 83/83/83 84/84/84 49/49/49 +f 85/85/85 62/62/62 86/86/86 +f 20/20/20 19/19/19 87/87/87 +f 40/40/40 25/25/25 11/11/11 +f 88/88/88 89/89/89 90/90/90 +f 91/91/91 92/92/92 93/93/93 +f 94/94/94 95/95/95 96/96/96 +f 97/97/97 98/98/98 99/99/99 +f 100/100/100 67/67/67 15/15/15 +f 88/88/88 101/101/101 102/102/102 +f 103/103/103 104/104/104 105/105/105 +f 89/89/89 88/88/88 106/106/106 +f 64/64/64 107/107/107 108/108/108 +f 109/109/109 14/14/14 110/110/110 +f 111/111/111 112/112/112 113/113/113 +f 114/114/114 115/115/115 116/116/116 +f 117/117/117 118/118/118 31/31/31 +f 60/60/60 119/119/119 120/120/120 +f 14/14/14 109/109/109 121/121/121 +f 122/122/122 123/123/123 124/124/124 +f 69/69/69 68/68/68 125/125/125 +f 34/34/34 126/126/126 87/87/87 +f 17/17/17 16/16/16 28/28/28 +f 127/127/127 59/59/59 75/75/75 +f 42/42/42 128/128/128 9/9/9 +f 129/129/129 130/130/130 94/94/94 +f 131/131/131 124/124/124 123/123/123 +f 132/132/132 133/133/133 134/134/134 +f 135/135/135 136/136/136 137/137/137 +f 138/138/138 139/139/139 140/140/140 +f 135/135/135 124/124/124 131/131/131 +f 141/141/141 2/2/2 142/142/142 +f 143/143/143 103/103/103 144/144/144 +f 145/145/145 146/146/146 147/147/147 +f 97/97/97 125/125/125 68/68/68 +f 148/148/148 85/85/85 76/76/76 +f 115/115/115 149/149/149 150/150/150 +f 11/11/11 6/6/6 151/151/151 +f 79/79/79 78/78/78 152/152/152 +f 86/86/86 153/153/153 110/110/110 +f 154/154/154 45/45/45 44/44/44 +f 133/133/133 155/155/155 108/108/108 +f 93/93/93 92/92/92 57/57/57 +f 156/156/156 129/129/129 157/157/157 +f 53/53/53 91/91/91 158/158/158 +f 33/33/33 44/44/44 159/159/159 +f 157/157/157 160/160/160 135/135/135 +f 127/127/127 44/44/44 33/33/33 +f 139/139/139 50/50/50 74/74/74 +f 161/161/161 143/143/143 162/162/162 +f 163/163/163 164/164/164 10/10/10 +f 62/62/62 165/165/165 153/153/153 +f 166/166/166 64/64/64 167/167/167 +f 118/118/118 168/168/168 166/166/166 +f 163/163/163 24/24/24 35/35/35 +f 45/45/45 148/148/148 169/169/169 +f 38/38/38 35/35/35 170/170/170 +f 171/171/171 126/126/126 34/34/34 +f 126/126/126 172/172/172 173/173/173 +f 174/174/174 175/175/175 16/16/16 +f 176/176/176 177/177/177 101/101/101 +f 143/143/143 178/178/178 77/77/77 +f 140/140/140 74/74/74 81/81/81 +f 179/179/179 106/106/106 180/180/180 +f 181/181/181 81/81/81 182/182/182 +f 23/23/23 110/110/110 9/9/9 +f 131/131/131 174/174/174 15/15/15 +f 183/183/183 161/161/161 142/142/142 +f 184/184/184 185/185/185 83/83/83 +f 165/165/165 168/168/168 118/118/118 +f 186/186/186 187/187/187 185/185/185 +f 106/106/106 102/102/102 26/26/26 +f 110/110/110 14/14/14 13/13/13 +f 188/188/188 73/73/73 150/150/150 +f 189/189/189 181/181/181 190/190/190 +f 177/177/177 176/176/176 99/99/99 +f 189/189/189 191/191/191 140/140/140 +f 192/192/192 193/193/193 119/119/119 +f 194/194/194 195/195/195 193/193/193 +f 30/30/30 29/29/29 196/196/196 +f 38/38/38 37/37/37 197/197/197 +f 198/198/198 98/98/98 68/68/68 +f 127/127/127 52/52/52 51/51/51 +f 19/19/19 18/18/18 199/199/199 +f 197/197/197 200/200/200 164/164/164 +f 124/124/124 135/135/135 160/160/160 +f 71/71/71 201/201/201 202/202/202 +f 123/123/123 179/179/179 175/175/175 +f 43/43/43 104/104/104 103/103/103 +f 2/2/2 1/1/1 203/203/203 +f 180/180/180 28/28/28 16/16/16 +f 204/204/204 28/28/28 27/27/27 +f 29/29/29 166/166/166 205/205/205 +f 139/139/139 138/138/138 206/206/206 +f 165/165/165 117/117/117 109/109/109 +f 144/144/144 156/156/156 141/141/141 +f 103/103/103 143/143/143 22/22/22 +f 207/207/207 179/179/179 123/123/123 +f 147/147/147 146/146/146 208/208/208 +f 209/209/209 106/106/106 179/179/179 +f 98/98/98 198/198/198 210/210/210 +f 211/211/211 212/212/212 213/213/213 +f 214/214/214 215/215/215 145/145/145 +f 136/136/136 66/66/66 3/3/3 +f 176/176/176 88/88/88 216/216/216 +f 94/94/94 130/130/130 213/213/213 +f 66/66/66 65/65/65 217/217/217 +f 126/126/126 171/171/171 120/120/120 +f 218/218/218 219/219/219 99/99/99 +f 148/148/148 41/41/41 40/40/40 +f 220/220/220 107/107/107 151/151/151 +f 208/208/208 146/146/146 221/221/221 +f 222/222/222 151/151/151 6/6/6 +f 10/10/10 164/164/164 223/223/223 +f 164/164/164 200/200/200 224/224/224 +f 131/131/131 67/67/67 66/66/66 +f 129/129/129 156/156/156 144/144/144 +f 23/23/23 22/22/22 76/76/76 +f 85/85/85 40/40/40 63/63/63 +f 117/117/117 225/225/225 121/121/121 +f 63/63/63 151/151/151 107/107/107 +f 214/214/214 30/30/30 113/113/113 +f 226/226/226 227/227/227 228/228/228 +f 229/229/229 132/132/132 221/221/221 +f 46/46/46 60/60/60 171/171/171 +f 230/230/230 58/58/58 226/226/226 +f 19/19/19 152/152/152 231/231/231 +f 146/146/146 145/145/145 215/215/215 +f 185/185/185 187/187/187 232/232/232 +f 83/83/83 185/185/185 190/190/190 +f 84/84/84 83/83/83 182/182/182 +f 47/47/47 84/84/84 82/82/82 +f 78/78/78 47/47/47 80/80/80 +f 161/161/161 183/183/183 233/233/233 +f 50/50/50 139/139/139 39/39/39 +f 51/51/51 50/50/50 170/170/170 +f 154/154/154 51/51/51 36/36/36 +f 45/45/45 154/154/154 41/41/41 +f 46/46/46 169/169/169 77/77/77 +f 2/2/2 141/141/141 137/137/137 +f 112/112/112 229/229/229 215/215/215 +f 143/143/143 161/161/161 234/234/234 +f 145/145/145 235/235/235 70/70/70 +f 78/78/78 32/32/32 231/231/231 +f 166/166/166 168/168/168 165/165/165 +f 236/236/236 194/194/194 192/192/192 +f 237/237/237 111/111/111 196/196/196 +f 134/134/134 108/108/108 107/107/107 +f 220/220/220 238/238/238 208/208/208 +f 239/239/239 237/237/237 205/205/205 +f 72/72/72 202/202/202 104/104/104 +f 211/211/211 130/130/130 129/129/129 +f 73/73/73 72/72/72 43/43/43 +f 150/150/150 73/73/73 42/42/42 +f 116/116/116 150/150/150 8/8/8 +f 227/227/227 116/116/116 7/7/7 +f 89/89/89 230/230/230 228/228/228 +f 209/209/209 56/56/56 230/230/230 +f 93/93/93 56/56/56 209/209/209 +f 158/158/158 93/93/93 207/207/207 +f 54/54/54 158/158/158 122/122/122 +f 55/55/55 54/54/54 240/240/240 +f 94/94/94 55/55/55 160/160/160 +f 132/132/132 112/112/112 133/133/133 +f 111/111/111 237/237/237 239/239/239 +f 155/155/155 239/239/239 167/167/167 +f 178/178/178 234/234/234 194/194/194 +f 133/133/133 112/112/112 111/111/111 +f 77/77/77 178/178/178 236/236/236 +f 227/227/227 241/241/241 90/90/90 +f 241/241/241 12/12/12 216/216/216 +f 12/12/12 242/242/242 218/218/218 +f 242/242/242 121/121/121 219/219/219 +f 31/31/31 30/30/30 214/214/214 +f 121/121/121 225/225/225 97/97/97 +f 225/225/225 31/31/31 125/125/125 +f 234/234/234 233/233/233 195/195/195 +f 141/141/141 156/156/156 243/243/243 +f 202/202/202 201/201/201 212/212/212 +f 104/104/104 202/202/202 211/211/211 +f 244/244/244 245/245/245 246/246/246 +f 4/4/4 247/247/247 248/248/248 +f 249/249/249 250/250/250 251/251/251 +f 247/247/247 252/252/252 253/253/253 +f 254/254/254 255/255/255 256/256/256 +f 249/249/249 257/257/257 254/254/254 +f 258/258/258 259/259/259 260/260/260 +f 18/18/18 261/261/261 262/262/262 +f 263/263/263 264/264/264 265/265/265 +f 252/252/252 266/266/266 267/267/267 +f 26/26/26 268/268/268 269/269/269 +f 270/270/270 271/271/271 272/272/272 +f 273/273/273 274/274/274 275/275/275 +f 266/266/266 276/276/276 277/277/277 +f 278/278/278 279/279/279 280/280/280 +f 267/267/267 277/277/277 281/281/281 +f 282/282/282 264/264/264 263/263/263 +f 283/283/283 284/284/284 285/285/285 +f 286/286/286 287/287/287 49/49/49 +f 288/288/288 289/289/289 290/290/290 +f 291/291/291 292/292/292 293/293/293 +f 294/294/294 295/295/295 296/296/296 +f 297/297/297 298/298/298 273/273/273 +f 299/299/299 300/300/300 301/301/301 +f 302/302/302 303/303/303 304/304/304 +f 305/305/305 306/306/306 307/307/307 +f 308/308/308 309/309/309 70/70/70 +f 310/310/310 311/311/311 312/312/312 +f 289/289/289 313/313/313 314/314/314 +f 315/315/315 316/316/316 317/317/317 +f 318/318/318 286/286/286 48/48/48 +f 314/314/314 319/319/319 298/298/298 +f 313/313/313 320/320/320 319/319/319 +f 321/321/321 322/322/322 49/49/49 +f 323/323/323 315/315/315 324/324/324 +f 262/262/262 325/325/325 326/326/326 +f 327/327/327 328/328/328 253/253/253 +f 329/329/329 330/330/330 331/331/331 +f 332/332/332 333/333/333 334/334/334 +f 335/335/335 293/293/293 292/292/292 +f 336/336/336 337/337/337 338/338/338 +f 306/306/306 259/259/259 258/258/258 +f 329/329/329 339/339/339 102/102/102 +f 340/340/340 341/341/341 342/342/342 +f 343/343/343 344/344/344 339/339/339 +f 304/304/304 345/345/345 346/346/346 +f 347/347/347 348/348/348 349/349/349 +f 350/350/350 351/351/351 352/352/352 +f 353/353/353 354/354/354 355/355/355 +f 356/356/356 357/357/357 272/272/272 +f 299/299/299 358/358/358 359/359/359 +f 256/256/256 255/255/255 360/360/360 +f 361/361/361 362/362/362 363/363/363 +f 364/364/364 365/365/365 366/366/366 +f 275/275/275 274/274/274 326/326/326 +f 260/260/260 367/367/367 269/269/269 +f 368/368/368 290/290/290 314/314/314 +f 282/282/282 369/369/369 251/251/251 +f 370/370/370 371/371/371 372/372/372 +f 373/373/373 374/374/374 375/375/375 +f 376/376/376 377/377/377 378/378/378 +f 379/379/379 380/380/380 381/381/381 +f 382/382/382 383/383/383 384/384/384 +f 379/379/379 385/385/385 373/373/373 +f 386/386/386 387/387/387 388/388/388 +f 389/389/389 387/387/387 341/341/341 +f 390/390/390 235/235/235 147/147/147 +f 336/336/336 391/391/391 308/308/308 +f 392/392/392 316/316/316 315/315/315 +f 393/393/393 355/355/355 394/394/394 +f 253/253/253 328/328/328 395/395/395 +f 79/79/79 199/199/199 396/396/396 +f 324/324/324 265/265/265 349/349/349 +f 397/397/397 368/368/368 283/283/283 +f 398/398/398 378/378/378 346/346/346 +f 334/334/334 294/294/294 399/399/399 +f 400/400/400 380/380/380 371/371/371 +f 291/291/291 401/401/401 333/333/333 +f 402/402/402 275/275/275 284/284/284 +f 371/371/371 380/380/380 379/379/379 +f 368/368/368 297/297/297 402/402/402 +f 403/403/403 384/384/384 289/289/289 +f 404/404/404 388/388/388 387/387/387 +f 405/405/405 252/252/252 247/247/247 +f 302/302/302 324/324/324 348/348/348 +f 406/406/406 407/407/407 345/345/345 +f 271/271/271 270/270/270 406/406/406 +f 405/405/405 408/408/408 266/266/266 +f 409/409/409 285/285/285 316/316/316 +f 408/408/408 280/280/280 276/276/276 +f 358/358/358 284/284/284 275/275/275 +f 410/410/410 326/326/326 325/325/325 +f 374/374/374 258/258/258 411/411/411 +f 412/412/412 329/329/329 101/101/101 +f 389/389/389 413/413/413 317/317/317 +f 384/384/384 414/414/414 313/313/313 +f 415/415/415 416/416/416 268/268/268 +f 414/414/414 417/417/417 320/320/320 +f 265/265/265 264/264/264 251/251/251 +f 373/373/373 307/307/307 258/258/258 +f 418/418/418 419/419/419 388/388/388 +f 184/184/184 322/322/322 321/321/321 +f 303/303/303 356/356/356 271/271/271 +f 186/186/186 184/184/184 420/420/420 +f 339/339/339 268/268/268 26/26/26 +f 349/349/349 251/251/251 250/250/250 +f 311/311/311 421/421/421 394/394/394 +f 422/422/422 423/423/423 417/417/417 +f 177/177/177 210/210/210 338/338/338 +f 422/422/422 414/414/414 384/384/384 +f 300/300/300 299/299/299 424/424/424 +f 425/425/425 300/300/300 426/426/426 +f 427/427/427 352/352/352 351/351/351 +f 408/408/408 405/405/405 428/428/428 +f 198/198/198 309/309/309 308/308/308 +f 368/368/368 397/397/397 429/429/429 +f 430/430/430 396/396/396 199/199/199 +f 428/428/428 405/405/405 431/431/431 +f 363/363/363 362/362/362 432/432/432 +f 310/310/310 433/433/433 434/434/434 +f 375/375/375 374/374/374 416/416/416 +f 435/435/435 263/263/263 340/340/340 +f 436/436/436 388/388/388 419/419/419 +f 268/268/268 416/416/416 411/411/411 +f 367/367/367 437/437/437 27/27/27 +f 270/270/270 351/351/351 407/407/407 +f 403/403/403 280/280/280 279/279/279 +f 303/303/303 348/348/348 347/347/347 +f 341/341/341 387/387/387 386/386/386 +f 340/340/340 263/263/263 413/413/413 +f 438/438/438 361/361/361 375/375/375 +f 147/147/147 238/238/238 439/439/439 +f 344/344/344 438/438/438 415/415/415 +f 391/391/391 338/338/338 210/210/210 +f 440/440/440 441/441/441 442/442/442 +f 365/365/365 364/364/364 390/390/390 +f 385/385/385 381/381/381 246/246/246 +f 412/412/412 443/443/443 330/330/330 +f 440/440/440 372/372/372 335/335/335 +f 444/444/444 246/246/246 245/245/245 +f 410/410/410 445/445/445 359/359/359 +f 443/443/443 412/412/412 338/338/338 +f 392/392/392 323/323/323 327/327/327 +f 220/220/220 222/222/222 395/395/395 +f 439/439/439 378/378/378 377/377/377 +f 222/222/222 5/5/5 248/248/248 +f 247/247/247 4/4/4 223/223/223 +f 431/431/431 223/223/223 224/224/224 +f 373/373/373 385/385/385 444/444/444 +f 370/370/370 342/342/342 341/341/341 +f 265/265/265 324/324/324 315/315/315 +f 323/323/323 302/302/302 328/328/328 +f 356/356/356 347/347/347 360/360/360 +f 328/328/328 304/304/304 446/446/446 +f 365/365/365 447/447/447 352/352/352 +f 354/354/354 353/353/353 448/448/448 +f 449/449/449 447/447/447 377/377/377 +f 285/285/285 284/284/284 358/358/358 +f 295/295/295 450/450/450 448/448/448 +f 430/430/430 326/326/326 274/274/274 +f 451/451/451 377/377/377 447/447/447 +f 420/420/420 417/417/417 423/423/423 +f 321/321/321 320/320/320 417/417/417 +f 287/287/287 319/319/319 320/320/320 +f 286/286/286 298/298/298 319/319/319 +f 318/318/318 273/273/273 298/298/298 +f 404/404/404 452/452/452 453/453/453 +f 288/288/288 276/276/276 280/280/280 +f 429/429/429 277/277/277 276/276/276 +f 397/397/397 281/281/281 277/277/277 +f 409/409/409 392/392/392 281/281/281 +f 285/285/285 301/301/301 317/317/317 +f 436/436/436 246/246/246 381/381/381 +f 454/454/454 352/352/352 447/447/447 +f 389/389/389 455/455/455 452/452/452 +f 390/390/390 364/364/364 70/70/70 +f 318/318/318 396/396/396 274/274/274 +f 406/406/406 304/304/304 303/303/303 +f 456/456/456 301/301/301 300/300/300 +f 457/457/457 407/407/407 351/351/351 +f 378/378/378 439/439/439 446/446/446 +f 220/220/220 446/446/446 439/439/439 +f 458/458/458 345/345/345 407/407/407 +f 433/433/433 435/435/435 459/459/459 +f 441/441/441 342/342/342 370/370/370 +f 312/312/312 282/282/282 435/435/435 +f 394/394/394 369/369/369 282/282/282 +f 355/355/355 249/249/249 369/369/369 +f 354/354/354 257/257/257 249/249/249 +f 343/343/343 331/331/331 450/450/450 +f 344/344/344 343/343/343 295/295/295 +f 334/334/334 438/438/438 344/344/344 +f 333/333/333 361/361/361 438/438/438 +f 401/401/401 362/362/362 361/361/361 +f 293/293/293 432/432/432 362/362/362 +f 372/372/372 371/371/371 432/432/432 +f 449/449/449 376/376/376 398/398/398 +f 457/457/457 350/350/350 460/460/460 +f 460/460/460 346/346/346 345/345/345 +f 455/455/455 456/456/456 425/425/425 +f 398/398/398 460/460/460 350/350/350 +f 317/317/317 301/301/301 456/456/456 +f 354/354/354 450/450/450 331/331/331 +f 257/257/257 331/331/331 330/330/330 +f 254/254/254 330/330/330 443/443/443 +f 255/255/255 443/443/443 337/337/337 +f 272/272/272 366/366/366 365/365/365 +f 360/360/360 337/337/337 336/336/336 +f 357/357/357 336/336/336 366/366/366 +f 452/452/452 425/425/425 461/461/461 +f 386/386/386 381/381/381 380/380/380 +f 434/434/434 441/441/441 462/462/462 +f 459/459/459 342/342/342 441/441/441 +f 226/226/226 228/228/228 230/230/230 +f 226/226/226 114/114/114 227/227/227 +f 213/213/213 95/95/95 94/94/94 +f 213/213/213 130/130/130 211/211/211 +f 296/296/296 399/399/399 294/294/294 +f 448/448/448 296/296/296 295/295/295 +f 448/448/448 450/450/450 354/354/354 +f 440/440/440 442/442/442 372/372/372 +f 440/440/440 462/462/462 441/441/441 +f 335/335/335 372/372/372 293/293/293 +f 239/239/239 155/155/155 111/111/111 +f 132/132/132 229/229/229 112/112/112 +f 217/217/217 1/1/1 3/3/3 +f 10/10/10 4/4/4 6/6/6 +f 13/13/13 7/7/7 9/9/9 +f 24/24/24 10/10/10 11/11/11 +f 242/242/242 12/12/12 14/14/14 +f 241/241/241 7/7/7 12/12/12 +f 463/463/463 15/15/15 17/17/17 +f 261/261/261 18/18/18 20/20/20 +f 128/128/128 21/21/21 23/23/23 +f 35/35/35 24/24/24 25/25/25 +f 180/180/180 26/26/26 28/28/28 +f 118/118/118 29/29/29 31/31/31 +f 231/231/231 32/32/32 34/34/34 +f 170/170/170 35/35/35 36/36/36 +f 206/206/206 37/37/37 39/39/39 +f 36/36/36 25/25/25 41/41/41 +f 128/128/128 42/42/42 21/21/21 +f 159/159/159 44/44/44 46/46/46 +f 84/84/84 47/47/47 49/49/49 +f 74/74/74 50/50/50 52/52/52 +f 96/96/96 53/53/53 55/55/55 +f 230/230/230 56/56/56 58/58/58 +f 80/80/80 59/59/59 32/32/32 +f 192/192/192 60/60/60 61/61/61 +f 165/165/165 62/62/62 64/64/64 +f 100/100/100 65/65/65 67/67/67 +f 309/309/309 68/68/68 70/70/70 +f 188/188/188 71/71/71 73/73/73 +f 81/81/81 74/74/74 75/75/75 +f 169/169/169 76/76/76 77/77/77 +f 47/47/47 78/78/78 48/48/48 +f 82/82/82 75/75/75 80/80/80 +f 182/182/182 81/81/81 82/82/82 +f 322/322/322 83/83/83 49/49/49 +f 76/76/76 85/85/85 86/86/86 +f 173/173/173 20/20/20 87/87/87 +f 63/63/63 40/40/40 11/11/11 +f 216/216/216 88/88/88 90/90/90 +f 158/158/158 91/91/91 93/93/93 +f 55/55/55 94/94/94 96/96/96 +f 219/219/219 97/97/97 99/99/99 +f 463/463/463 100/100/100 15/15/15 +f 106/106/106 88/88/88 102/102/102 +f 144/144/144 103/103/103 105/105/105 +f 209/209/209 89/89/89 106/106/106 +f 167/167/167 64/64/64 108/108/108 +f 153/153/153 109/109/109 110/110/110 +f 196/196/196 111/111/111 113/113/113 +f 227/227/227 114/114/114 116/116/116 +f 225/225/225 117/117/117 31/31/31 +f 171/171/171 60/60/60 120/120/120 +f 242/242/242 14/14/14 121/121/121 +f 240/240/240 122/122/122 124/124/124 +f 214/214/214 69/69/69 125/125/125 +f 231/231/231 34/34/34 87/87/87 +f 204/204/204 17/17/17 28/28/28 +f 52/52/52 127/127/127 75/75/75 +f 8/8/8 42/42/42 9/9/9 +f 157/157/157 129/129/129 94/94/94 +f 174/174/174 131/131/131 123/123/123 +f 221/221/221 132/132/132 134/134/134 +f 243/243/243 135/135/135 137/137/137 +f 191/191/191 138/138/138 140/140/140 +f 136/136/136 135/135/135 131/131/131 +f 162/162/162 141/141/141 142/142/142 +f 162/162/162 143/143/143 144/144/144 +f 235/235/235 145/145/145 147/147/147 +f 98/98/98 97/97/97 68/68/68 +f 169/169/169 148/148/148 76/76/76 +f 116/116/116 115/115/115 150/150/150 +f 63/63/63 11/11/11 151/151/151 +f 199/199/199 79/79/79 152/152/152 +f 23/23/23 86/86/86 110/110/110 +f 127/127/127 154/154/154 44/44/44 +f 134/134/134 133/133/133 108/108/108 +f 56/56/56 93/93/93 57/57/57 +f 243/243/243 156/156/156 157/157/157 +f 54/54/54 53/53/53 158/158/158 +f 34/34/34 33/33/33 159/159/159 +f 243/243/243 157/157/157 135/135/135 +f 59/59/59 127/127/127 33/33/33 +f 140/140/140 139/139/139 74/74/74 +f 142/142/142 161/161/161 162/162/162 +f 24/24/24 163/163/163 10/10/10 +f 86/86/86 62/62/62 153/153/153 +f 205/205/205 166/166/166 167/167/167 +f 29/29/29 118/118/118 166/166/166 +f 38/38/38 163/163/163 35/35/35 +f 46/46/46 45/45/45 169/169/169 +f 39/39/39 38/38/38 170/170/170 +f 159/159/159 171/171/171 34/34/34 +f 87/87/87 126/126/126 173/173/173 +f 15/15/15 174/174/174 16/16/16 +f 88/88/88 176/176/176 101/101/101 +f 22/22/22 143/143/143 77/77/77 +f 181/181/181 140/140/140 81/81/81 +f 175/175/175 179/179/179 180/180/180 +f 190/190/190 181/181/181 182/182/182 +f 128/128/128 23/23/23 9/9/9 +f 67/67/67 131/131/131 15/15/15 +f 203/203/203 183/183/183 142/142/142 +f 322/322/322 184/184/184 83/83/83 +f 117/117/117 165/165/165 118/118/118 +f 184/184/184 186/186/186 185/185/185 +f 180/180/180 106/106/106 26/26/26 +f 9/9/9 110/110/110 13/13/13 +f 149/149/149 188/188/188 150/150/150 +f 232/232/232 189/189/189 190/190/190 +f 210/210/210 177/177/177 99/99/99 +f 181/181/181 189/189/189 140/140/140 +f 60/60/60 192/192/192 119/119/119 +f 192/192/192 194/194/194 193/193/193 +f 113/113/113 30/30/30 196/196/196 +f 163/163/163 38/38/38 197/197/197 +f 309/309/309 198/198/198 68/68/68 +f 154/154/154 127/127/127 51/51/51 +f 152/152/152 19/19/19 199/199/199 +f 163/163/163 197/197/197 164/164/164 +f 240/240/240 124/124/124 160/160/160 +f 72/72/72 71/71/71 202/202/202 +f 174/174/174 123/123/123 175/175/175 +f 21/21/21 43/43/43 103/103/103 +f 142/142/142 2/2/2 203/203/203 +f 175/175/175 180/180/180 16/16/16 +f 437/437/437 204/204/204 27/27/27 +f 196/196/196 29/29/29 205/205/205 +f 39/39/39 139/139/139 206/206/206 +f 153/153/153 165/165/165 109/109/109 +f 162/162/162 144/144/144 141/141/141 +f 21/21/21 103/103/103 22/22/22 +f 122/122/122 207/207/207 123/123/123 +f 238/238/238 147/147/147 208/208/208 +f 207/207/207 209/209/209 179/179/179 +f 99/99/99 98/98/98 210/210/210 +f 69/69/69 214/214/214 145/145/145 +f 137/137/137 136/136/136 3/3/3 +f 218/218/218 176/176/176 216/216/216 +f 3/3/3 66/66/66 217/217/217 +f 172/172/172 126/126/126 120/120/120 +f 176/176/176 218/218/218 99/99/99 +f 85/85/85 148/148/148 40/40/40 +f 222/222/222 220/220/220 151/151/151 +f 134/134/134 208/208/208 221/221/221 +f 5/5/5 222/222/222 6/6/6 +f 4/4/4 10/10/10 223/223/223 +f 223/223/223 164/164/164 224/224/224 +f 136/136/136 131/131/131 66/66/66 +f 105/105/105 129/129/129 144/144/144 +f 86/86/86 23/23/23 76/76/76 +f 62/62/62 85/85/85 63/63/63 +f 109/109/109 117/117/117 121/121/121 +f 64/64/64 63/63/63 107/107/107 +f 215/215/215 214/214/214 113/113/113 +f 215/215/215 229/229/229 221/221/221 +f 159/159/159 46/46/46 171/171/171 +f 87/87/87 19/19/19 231/231/231 +f 221/221/221 146/146/146 215/215/215 +f 190/190/190 185/185/185 232/232/232 +f 182/182/182 83/83/83 190/190/190 +f 82/82/82 84/84/84 182/182/182 +f 80/80/80 47/47/47 82/82/82 +f 32/32/32 78/78/78 80/80/80 +f 234/234/234 161/161/161 233/233/233 +f 170/170/170 50/50/50 39/39/39 +f 36/36/36 51/51/51 170/170/170 +f 41/41/41 154/154/154 36/36/36 +f 148/148/148 45/45/45 41/41/41 +f 61/61/61 46/46/46 77/77/77 +f 3/3/3 2/2/2 137/137/137 +f 113/113/113 112/112/112 215/215/215 +f 178/178/178 143/143/143 234/234/234 +f 69/69/69 145/145/145 70/70/70 +f 152/152/152 78/78/78 231/231/231 +f 64/64/64 166/166/166 165/165/165 +f 61/61/61 236/236/236 192/192/192 +f 205/205/205 237/237/237 196/196/196 +f 208/208/208 134/134/134 107/107/107 +f 107/107/107 220/220/220 208/208/208 +f 167/167/167 239/239/239 205/205/205 +f 43/43/43 72/72/72 104/104/104 +f 105/105/105 211/211/211 129/129/129 +f 42/42/42 73/73/73 43/43/43 +f 8/8/8 150/150/150 42/42/42 +f 7/7/7 116/116/116 8/8/8 +f 241/241/241 227/227/227 7/7/7 +f 90/90/90 89/89/89 228/228/228 +f 89/89/89 209/209/209 230/230/230 +f 207/207/207 93/93/93 209/209/209 +f 122/122/122 158/158/158 207/207/207 +f 240/240/240 54/54/54 122/122/122 +f 160/160/160 55/55/55 240/240/240 +f 157/157/157 94/94/94 160/160/160 +f 108/108/108 155/155/155 167/167/167 +f 236/236/236 178/178/178 194/194/194 +f 155/155/155 133/133/133 111/111/111 +f 61/61/61 77/77/77 236/236/236 +f 228/228/228 227/227/227 90/90/90 +f 90/90/90 241/241/241 216/216/216 +f 216/216/216 12/12/12 218/218/218 +f 218/218/218 242/242/242 219/219/219 +f 125/125/125 31/31/31 214/214/214 +f 219/219/219 121/121/121 97/97/97 +f 97/97/97 225/225/225 125/125/125 +f 194/194/194 234/234/234 195/195/195 +f 137/137/137 141/141/141 243/243/243 +f 211/211/211 202/202/202 212/212/212 +f 105/105/105 104/104/104 211/211/211 +f 436/436/436 244/244/244 246/246/246 +f 5/5/5 4/4/4 248/248/248 +f 369/369/369 249/249/249 251/251/251 +f 248/248/248 247/247/247 253/253/253 +f 250/250/250 254/254/254 256/256/256 +f 250/250/250 249/249/249 254/254/254 +f 411/411/411 258/258/258 260/260/260 +f 430/430/430 18/18/18 262/262/262 +f 413/413/413 263/263/263 265/265/265 +f 253/253/253 252/252/252 267/267/267 +f 27/27/27 26/26/26 269/269/269 +f 427/427/427 270/270/270 272/272/272 +f 402/402/402 273/273/273 275/275/275 +f 267/267/267 266/266/266 277/277/277 +f 408/408/408 278/278/278 280/280/280 +f 327/327/327 267/267/267 281/281/281 +f 435/435/435 282/282/282 263/263/263 +f 409/409/409 283/283/283 285/285/285 +f 48/48/48 286/286/286 49/49/49 +f 429/429/429 288/288/288 290/290/290 +f 401/401/401 291/291/291 293/293/293 +f 402/402/402 297/297/297 273/273/273 +f 285/285/285 299/299/299 301/301/301 +f 328/328/328 302/302/302 304/304/304 +f 444/444/444 305/305/305 307/307/307 +f 364/364/364 308/308/308 70/70/70 +f 433/433/433 310/310/310 312/312/312 +f 290/290/290 289/289/289 314/314/314 +f 413/413/413 315/315/315 317/317/317 +f 79/79/79 318/318/318 48/48/48 +f 297/297/297 314/314/314 298/298/298 +f 314/314/314 313/313/313 319/319/319 +f 287/287/287 321/321/321 49/49/49 +f 302/302/302 323/323/323 324/324/324 +f 430/430/430 262/262/262 326/326/326 +f 267/267/267 327/327/327 253/253/253 +f 343/343/343 329/329/329 331/331/331 +f 464/464/464 332/332/332 334/334/334 +f 391/391/391 336/336/336 338/338/338 +f 307/307/307 306/306/306 258/258/258 +f 101/101/101 329/329/329 102/102/102 +f 459/459/459 340/340/340 342/342/342 +f 329/329/329 343/343/343 339/339/339 +f 446/446/446 304/304/304 346/346/346 +f 256/256/256 347/347/347 349/349/349 +f 454/454/454 350/350/350 352/352/352 +f 393/393/393 353/353/353 355/355/355 +f 271/271/271 356/356/356 272/272/272 +f 424/424/424 299/299/299 359/359/359 +f 347/347/347 256/256/256 360/360/360 +f 375/375/375 361/361/361 363/363/363 +f 308/308/308 364/364/364 366/366/366 +f 410/410/410 275/275/275 326/326/326 +f 411/411/411 260/260/260 269/269/269 +f 297/297/297 368/368/368 314/314/314 +f 264/264/264 282/282/282 251/251/251 +f 442/442/442 370/370/370 372/372/372 +f 363/363/363 373/373/373 375/375/375 +f 398/398/398 376/376/376 378/378/378 +f 385/385/385 379/379/379 381/381/381 +f 403/403/403 382/382/382 384/384/384 +f 363/363/363 379/379/379 373/373/373 +f 436/436/436 386/386/386 388/388/388 +f 340/340/340 389/389/389 341/341/341 +f 451/451/451 390/390/390 147/147/147 +f 366/366/366 336/336/336 308/308/308 +f 323/323/323 392/392/392 315/315/315 +f 421/421/421 393/393/393 394/394/394 +f 248/248/248 253/253/253 395/395/395 +f 318/318/318 79/79/79 396/396/396 +f 348/348/348 324/324/324 349/349/349 +f 409/409/409 397/397/397 283/283/283 +f 460/460/460 398/398/398 346/346/346 +f 464/464/464 334/334/334 399/399/399 +f 370/370/370 400/400/400 371/371/371 +f 332/332/332 291/291/291 333/333/333 +f 283/283/283 402/402/402 284/284/284 +f 432/432/432 371/371/371 379/379/379 +f 283/283/283 368/368/368 402/402/402 +f 288/288/288 403/403/403 289/289/289 +f 389/389/389 404/404/404 387/387/387 +f 431/431/431 405/405/405 247/247/247 +f 303/303/303 302/302/302 348/348/348 +f 304/304/304 406/406/406 345/345/345 +f 465/465/465 271/271/271 406/406/406 +f 252/252/252 405/405/405 266/266/266 +f 392/392/392 409/409/409 316/316/316 +f 266/266/266 408/408/408 276/276/276 +f 410/410/410 358/358/358 275/275/275 +f 445/445/445 410/410/410 325/325/325 +f 416/416/416 374/374/374 411/411/411 +f 177/177/177 412/412/412 101/101/101 +f 455/455/455 389/389/389 317/317/317 +f 289/289/289 384/384/384 313/313/313 +f 339/339/339 415/415/415 268/268/268 +f 313/313/313 414/414/414 320/320/320 +f 349/349/349 265/265/265 251/251/251 +f 374/374/374 373/373/373 258/258/258 +f 404/404/404 418/418/418 388/388/388 +f 420/420/420 184/184/184 321/321/321 +f 465/465/465 303/303/303 271/271/271 +f 466/466/466 186/186/186 420/420/420 +f 102/102/102 339/339/339 26/26/26 +f 256/256/256 349/349/349 250/250/250 +f 312/312/312 311/311/311 394/394/394 +f 414/414/414 422/422/422 417/417/417 +f 412/412/412 177/177/177 338/338/338 +f 383/383/383 422/422/422 384/384/384 +f 426/426/426 300/300/300 424/424/424 +f 461/461/461 425/425/425 426/426/426 +f 270/270/270 427/427/427 351/351/351 +f 278/278/278 408/408/408 428/428/428 +f 391/391/391 198/198/198 308/308/308 +f 290/290/290 368/368/368 429/429/429 +f 18/18/18 430/430/430 199/199/199 +f 467/467/467 428/428/428 431/431/431 +f 379/379/379 363/363/363 432/432/432 +f 468/468/468 310/310/310 434/434/434 +f 415/415/415 375/375/375 416/416/416 +f 459/459/459 435/435/435 340/340/340 +f 244/244/244 436/436/436 419/419/419 +f 269/269/269 268/268/268 411/411/411 +f 269/269/269 367/367/367 27/27/27 +f 406/406/406 270/270/270 407/407/407 +f 382/382/382 403/403/403 279/279/279 +f 356/356/356 303/303/303 347/347/347 +f 400/400/400 341/341/341 386/386/386 +f 389/389/389 340/340/340 413/413/413 +f 415/415/415 438/438/438 375/375/375 +f 451/451/451 147/147/147 439/439/439 +f 339/339/339 344/344/344 415/415/415 +f 198/198/198 391/391/391 210/210/210 +f 447/447/447 365/365/365 390/390/390 +f 444/444/444 385/385/385 246/246/246 +f 329/329/329 412/412/412 330/330/330 +f 305/305/305 444/444/444 245/245/245 +f 358/358/358 410/410/410 359/359/359 +f 337/337/337 443/443/443 338/338/338 +f 281/281/281 392/392/392 327/327/327 +f 446/446/446 220/220/220 395/395/395 +f 451/451/451 439/439/439 377/377/377 +f 395/395/395 222/222/222 248/248/248 +f 431/431/431 247/247/247 223/223/223 +f 467/467/467 431/431/431 224/224/224 +f 307/307/307 373/373/373 444/444/444 +f 400/400/400 370/370/370 341/341/341 +f 413/413/413 265/265/265 315/315/315 +f 327/327/327 323/323/323 328/328/328 +f 357/357/357 356/356/356 360/360/360 +f 395/395/395 328/328/328 446/446/446 +f 427/427/427 365/365/365 352/352/352 +f 376/376/376 449/449/449 377/377/377 +f 299/299/299 285/285/285 358/358/358 +f 396/396/396 430/430/430 274/274/274 +f 390/390/390 451/451/451 447/447/447 +f 466/466/466 420/420/420 423/423/423 +f 420/420/420 321/321/321 417/417/417 +f 321/321/321 287/287/287 320/320/320 +f 287/287/287 286/286/286 319/319/319 +f 286/286/286 318/318/318 298/298/298 +f 418/418/418 404/404/404 453/453/453 +f 403/403/403 288/288/288 280/280/280 +f 288/288/288 429/429/429 276/276/276 +f 429/429/429 397/397/397 277/277/277 +f 397/397/397 409/409/409 281/281/281 +f 316/316/316 285/285/285 317/317/317 +f 386/386/386 436/436/436 381/381/381 +f 449/449/449 454/454/454 447/447/447 +f 404/404/404 389/389/389 452/452/452 +f 235/235/235 390/390/390 70/70/70 +f 273/273/273 318/318/318 274/274/274 +f 465/465/465 406/406/406 303/303/303 +f 425/425/425 456/456/456 300/300/300 +f 350/350/350 457/457/457 351/351/351 +f 346/346/346 378/378/378 446/446/446 +f 238/238/238 220/220/220 439/439/439 +f 457/457/457 458/458/458 407/407/407 +f 434/434/434 433/433/433 459/459/459 +f 442/442/442 441/441/441 370/370/370 +f 433/433/433 312/312/312 435/435/435 +f 312/312/312 394/394/394 282/282/282 +f 394/394/394 355/355/355 369/369/369 +f 355/355/355 354/354/354 249/249/249 +f 295/295/295 343/343/343 450/450/450 +f 294/294/294 344/344/344 295/295/295 +f 294/294/294 334/334/334 344/344/344 +f 334/334/334 333/333/333 438/438/438 +f 333/333/333 401/401/401 361/361/361 +f 401/401/401 293/293/293 362/362/362 +f 293/293/293 372/372/372 432/432/432 +f 454/454/454 449/449/449 398/398/398 +f 458/458/458 457/457/457 460/460/460 +f 458/458/458 460/460/460 345/345/345 +f 452/452/452 455/455/455 425/425/425 +f 454/454/454 398/398/398 350/350/350 +f 455/455/455 317/317/317 456/456/456 +f 257/257/257 354/354/354 331/331/331 +f 254/254/254 257/257/257 330/330/330 +f 255/255/255 254/254/254 443/443/443 +f 360/360/360 255/255/255 337/337/337 +f 427/427/427 272/272/272 365/365/365 +f 357/357/357 360/360/360 336/336/336 +f 272/272/272 357/357/357 366/366/366 +f 453/453/453 452/452/452 461/461/461 +f 400/400/400 386/386/386 380/380/380 +f 468/468/468 434/434/434 462/462/462 +f 434/434/434 459/459/459 441/441/441 +# 852 faces + diff --git a/hairline/mesh/face_ext.obj b/hairline/mesh/face_ext.obj new file mode 100644 index 0000000..9144ff5 --- /dev/null +++ b/hairline/mesh/face_ext.obj @@ -0,0 +1,2428 @@ +# head3d extended face mesh +# vertices=502 texcoords=502 normals=502 faces=916 + +v 0.1676 0.5092 0.2591 +v 0.1771 0.5141 0.1685 +v 0.1865 0.4618 0.1361 +v 0.4670 0.7575 -0.0631 +v 0.4671 0.7458 -0.0670 +v 0.4379 0.7395 -0.0631 +v 0.3892 0.5426 -0.0007 +v 0.3631 0.5501 0.0018 +v 0.3648 0.5691 -0.0028 +v 0.4383 0.7547 -0.0594 +v 0.4080 0.7493 -0.0466 +v 0.4142 0.5453 -0.0172 +v 0.3929 0.5585 -0.0115 +v 0.3953 0.5777 -0.0249 +v 0.2693 0.3555 -0.0041 +v 0.3317 0.3441 -0.0417 +v 0.3176 0.2901 -0.0208 +v 0.4645 0.9425 0.0141 +v 0.4131 0.9359 0.0208 +v 0.4148 0.9524 0.0567 +v 0.2764 0.5811 0.0178 +v 0.2618 0.6372 0.0203 +v 0.3218 0.6083 -0.0036 +v 0.4130 0.7599 -0.0441 +v 0.3882 0.7597 -0.0267 +v 0.4716 0.4160 -0.0756 +v 0.4717 0.3448 -0.0701 +v 0.3976 0.3432 -0.0630 +v 0.3969 0.6604 -0.0717 +v 0.4082 0.6504 -0.0986 +v 0.4081 0.6340 -0.0898 +v 0.3866 0.8650 0.0146 +v 0.3576 0.8424 0.0268 +v 0.3437 0.8641 0.0496 +v 0.3940 0.7654 -0.0259 +v 0.3753 0.7689 -0.0041 +v 0.4042 0.7765 -0.0144 +v 0.3997 0.7722 -0.0205 +v 0.3858 0.7742 -0.0038 +v 0.3656 0.7335 -0.0192 +v 0.3465 0.7519 0.0005 +v 0.3297 0.5547 0.0078 +v 0.2951 0.5537 0.0195 +v 0.3330 0.8122 0.0361 +v 0.3121 0.7799 0.0363 +v 0.2817 0.7829 0.0643 +v 0.4327 0.8532 -0.0060 +v 0.4654 0.8552 -0.0070 +v 0.4656 0.8296 -0.0366 +v 0.3696 0.7768 0.0149 +v 0.3665 0.7770 0.0190 +v 0.3761 0.7887 0.0050 +v 0.3077 0.4839 0.0049 +v 0.2906 0.4595 -0.0031 +v 0.2739 0.4710 0.0089 +v 0.3790 0.4711 -0.0057 +v 0.3737 0.4919 0.0003 +v 0.3911 0.5057 0.0066 +v 0.3754 0.8206 0.0083 +v 0.2726 0.8255 0.1227 +v 0.2492 0.7539 0.0989 +v 0.3648 0.6781 -0.0133 +v 0.3913 0.7208 -0.0338 +v 0.4049 0.6867 -0.0353 +v 0.1839 0.3975 0.1474 +v 0.2000 0.4179 0.0893 +v 0.2271 0.3808 0.0385 +v 0.4461 0.6108 -0.1335 +v 0.4449 0.6420 -0.1470 +v 0.4683 0.6424 -0.1505 +v 0.3130 0.5174 0.0122 +v 0.3092 0.5328 0.0113 +v 0.3340 0.5345 0.0034 +v 0.3805 0.7832 0.0001 +v 0.3891 0.8008 -0.0126 +v 0.3002 0.6720 -0.0008 +v 0.2473 0.6924 0.0531 +v 0.4243 0.8807 0.0009 +v 0.4652 0.8852 -0.0044 +v 0.4008 0.8398 -0.0021 +v 0.3934 0.7913 -0.0180 +v 0.4090 0.8158 -0.0252 +v 0.4368 0.8081 -0.0399 +v 0.4355 0.8259 -0.0348 +v 0.3387 0.7021 -0.0061 +v 0.3413 0.6423 -0.0146 +v 0.3707 0.9171 0.0457 +v 0.4398 0.4946 -0.0439 +v 0.4163 0.4924 -0.0098 +v 0.4205 0.5208 -0.0087 +v 0.3286 0.4800 -0.0027 +v 0.3507 0.4822 -0.0044 +v 0.3507 0.4573 -0.0138 +v 0.2650 0.4848 0.0259 +v 0.2885 0.4959 0.0245 +v 0.2953 0.4902 0.0145 +v 0.4299 0.5952 -0.0907 +v 0.4478 0.5842 -0.1103 +v 0.4469 0.5590 -0.0919 +v 0.2100 0.3506 0.0899 +v 0.4704 0.4907 -0.0625 +v 0.4708 0.4538 -0.0666 +v 0.2438 0.5706 0.0425 +v 0.2694 0.5454 0.0357 +v 0.2547 0.5342 0.0489 +v 0.4147 0.4479 -0.0578 +v 0.4381 0.6925 -0.0621 +v 0.4358 0.6881 -0.0632 +v 0.3997 0.6049 -0.0340 +v 0.3666 0.5924 -0.0138 +v 0.4158 0.6704 -0.0715 +v 0.4240 0.6662 -0.0985 +v 0.4162 0.6618 -0.1040 +v 0.3915 0.5162 0.0115 +v 0.3762 0.5164 0.0068 +v 0.3827 0.5290 0.0029 +v 0.4015 0.6264 -0.0480 +v 0.3951 0.6468 -0.0647 +v 0.2745 0.8529 0.1747 +v 0.3121 0.8883 0.1365 +v 0.4156 0.5873 -0.0517 +v 0.3094 0.4427 -0.0210 +v 0.2958 0.4235 -0.0338 +v 0.2595 0.4320 -0.0112 +v 0.4257 0.6190 -0.1166 +v 0.3369 0.8887 0.0738 +v 0.3553 0.8012 0.0189 +v 0.3268 0.5785 0.0047 +v 0.2483 0.5082 0.0545 +v 0.2680 0.5023 0.0429 +v 0.2444 0.4142 0.0007 +v 0.4447 0.6760 -0.1132 +v 0.4468 0.6819 -0.0886 +v 0.4518 0.6855 -0.0880 +v 0.2345 0.4506 0.0166 +v 0.2186 0.4376 0.0384 +v 0.2080 0.4730 0.0733 +v 0.3758 0.7767 0.0109 +v 0.3724 0.7765 0.0115 +v 0.3860 0.7805 -0.0004 +v 0.2017 0.5181 0.1021 +v 0.1794 0.5700 0.1817 +v 0.2078 0.6235 0.0945 +v 0.2264 0.5516 0.0656 +v 0.4481 0.6677 -0.1374 +v 0.4565 0.6808 -0.1238 +v 0.4680 0.6820 -0.1255 +v 0.3186 0.7336 0.0088 +v 0.3551 0.5186 0.0035 +v 0.3600 0.5332 0.0009 +v 0.4362 0.7131 -0.0588 +v 0.4161 0.9117 0.0047 +v 0.3756 0.6237 -0.0222 +v 0.3370 0.7750 0.0229 +v 0.4334 0.6829 -0.0627 +v 0.2232 0.5152 0.0750 +v 0.2488 0.4835 0.0338 +v 0.3185 0.4537 -0.0130 +v 0.3124 0.8326 0.0644 +v 0.2574 0.4627 0.0097 +v 0.1892 0.6268 0.1920 +v 0.2004 0.5675 0.0971 +v 0.4176 0.7696 -0.0389 +v 0.4403 0.7685 -0.0495 +v 0.3885 0.6596 -0.0216 +v 0.3968 0.6721 -0.0561 +v 0.4127 0.6839 -0.0509 +v 0.3910 0.6586 -0.0486 +v 0.2811 0.7127 0.0235 +v 0.3801 0.7717 -0.0038 +v 0.3058 0.8611 0.0987 +v 0.3436 0.9132 0.1068 +v 0.3766 0.9355 0.0767 +v 0.2857 0.4006 -0.0310 +v 0.3413 0.4028 -0.0575 +v 0.4461 0.5307 -0.0678 +v 0.4702 0.5253 -0.0786 +v 0.2170 0.6766 0.1074 +v 0.3464 0.4269 -0.0501 +v 0.4055 0.4113 -0.0715 +v 0.3989 0.7829 -0.0152 +v 0.4124 0.7997 -0.0300 +v 0.1829 0.6285 0.2903 +v 0.4662 0.7941 -0.0388 +v 0.4395 0.7914 -0.0353 +v 0.4667 0.7799 -0.0380 +v 0.4429 0.7777 -0.0344 +v 0.3334 0.5197 0.0053 +v 0.4044 0.7768 -0.0132 +v 0.4168 0.7866 -0.0268 +v 0.3914 0.7770 0.0008 +v 0.2412 0.7896 0.1540 +v 0.2439 0.8140 0.2214 +v 0.2163 0.7403 0.1861 +v 0.2171 0.7611 0.2620 +v 0.4046 0.6684 -0.0743 +v 0.4218 0.7757 -0.0259 +v 0.4693 0.5807 -0.1203 +v 0.4645 0.9176 -0.0027 +v 0.4427 0.7770 -0.0354 +v 0.3002 0.5130 0.0210 +v 0.2904 0.5279 0.0232 +v 0.1733 0.5677 0.2835 +v 0.3888 0.2791 -0.0510 +v 0.4062 0.6759 -0.0606 +v 0.3911 0.7769 -0.0000 +v 0.3491 0.4463 -0.0240 +v 0.4591 0.6886 -0.0877 +v 0.3948 0.4651 -0.0194 +v 0.4693 0.5547 -0.0987 +v 0.2793 0.5182 0.0339 +v 0.2917 0.5082 0.0285 +v 0.2830 0.5012 0.0372 +v 0.4253 0.6445 -0.1239 +v 0.4322 0.6630 -0.1245 +v 0.4292 0.5259 -0.0266 +v 0.1712 0.4480 0.2091 +v 0.4299 0.5441 -0.0501 +v 0.4302 0.5711 -0.0722 +v 0.4679 0.6942 -0.0697 +v 0.4487 0.6788 -0.1199 +v 0.4677 0.7135 -0.0618 +v 0.4672 0.7696 -0.0536 +v 0.4666 0.7789 -0.0387 +v 0.4143 0.6117 -0.0684 +v 0.3989 0.5145 0.0114 +v 0.3979 0.5234 0.0058 +v 0.4074 0.5155 0.0073 +v 0.4330 0.6672 -0.1115 +v 0.4015 0.4957 0.0009 +v 0.3750 0.8914 0.0272 +v 0.4221 0.7771 -0.0248 +v 0.1977 0.6930 0.2835 +v 0.2017 0.6854 0.1930 +v 0.4680 0.6685 -0.1399 +v 0.2263 0.7213 0.1205 +v 0.4161 0.6751 -0.0607 +v 0.4679 0.6893 -0.0895 +v 0.4217 0.6803 -0.0551 +v 0.2780 0.4493 -0.0086 +v 0.4070 0.5352 -0.0034 +v 0.4134 0.5615 -0.0359 +v 0.2270 0.4800 0.0463 +v 0.7744 0.5149 0.2502 +v 0.7717 0.4527 0.2009 +v 0.7564 0.4666 0.1289 +v 0.4961 0.7564 -0.0603 +v 0.4968 0.7409 -0.0641 +v 0.5513 0.5446 -0.0028 +v 0.5470 0.5601 -0.0137 +v 0.5759 0.5717 -0.0057 +v 0.5217 0.7633 -0.0460 +v 0.5265 0.7526 -0.0487 +v 0.5263 0.5464 -0.0187 +v 0.5258 0.5628 -0.0376 +v 0.5440 0.5794 -0.0271 +v 0.5326 0.5370 -0.0051 +v 0.6749 0.3576 -0.0091 +v 0.6914 0.3169 0.0245 +v 0.6266 0.2923 -0.0250 +v 0.4644 0.9578 0.0484 +v 0.5151 0.9534 0.0552 +v 0.6655 0.5852 0.0127 +v 0.6148 0.5816 0.0010 +v 0.6177 0.6115 -0.0074 +v 0.5414 0.7702 -0.0285 +v 0.5470 0.7642 -0.0296 +v 0.5384 0.4118 -0.0725 +v 0.5462 0.3442 -0.0649 +v 0.5404 0.6625 -0.0737 +v 0.5420 0.6489 -0.0668 +v 0.5294 0.6356 -0.0915 +v 0.5463 0.8663 0.0123 +v 0.5572 0.8928 0.0248 +v 0.5904 0.8660 0.0460 +v 0.5546 0.7769 -0.0072 +v 0.5597 0.7746 -0.0078 +v 0.5303 0.7798 -0.0166 +v 0.5433 0.7812 -0.0029 +v 0.5494 0.7797 -0.0068 +v 0.5895 0.7566 -0.0036 +v 0.6114 0.5583 0.0040 +v 0.6029 0.8160 0.0321 +v 0.6222 0.8358 0.0597 +v 0.6549 0.7875 0.0586 +v 0.4990 0.8532 -0.0067 +v 0.4972 0.8271 -0.0358 +v 0.5660 0.7828 0.0113 +v 0.5545 0.7887 -0.0031 +v 0.5593 0.7932 0.0014 +v 0.6346 0.4869 0.0005 +v 0.6476 0.4942 0.0098 +v 0.6703 0.4744 0.0038 +v 0.5633 0.4724 -0.0083 +v 0.5397 0.4974 -0.0014 +v 0.5495 0.5072 0.0040 +v 0.5582 0.8234 0.0052 +v 0.5322 0.8411 -0.0042 +v 0.6630 0.8297 0.1167 +v 0.6946 0.7937 0.1473 +v 0.6879 0.7587 0.0926 +v 0.5719 0.6809 -0.0160 +v 0.5485 0.6618 -0.0238 +v 0.5309 0.6890 -0.0369 +v 0.7595 0.4019 0.1394 +v 0.7337 0.3543 0.0828 +v 0.7165 0.3837 0.0323 +v 0.4907 0.6108 -0.1342 +v 0.4686 0.6085 -0.1422 +v 0.6285 0.5216 0.0079 +v 0.6083 0.5236 0.0014 +v 0.6071 0.5388 -0.0005 +v 0.5410 0.7954 -0.0205 +v 0.5457 0.8047 -0.0151 +v 0.6384 0.6759 -0.0051 +v 0.6567 0.7166 0.0184 +v 0.6916 0.6970 0.0471 +v 0.5070 0.8820 -0.0003 +v 0.5247 0.8179 -0.0270 +v 0.5220 0.8031 -0.0318 +v 0.4960 0.8096 -0.0407 +v 0.4663 0.8117 -0.0427 +v 0.5989 0.7052 -0.0097 +v 0.5967 0.6454 -0.0179 +v 0.5548 0.9369 0.0738 +v 0.5614 0.9182 0.0429 +v 0.5700 0.7367 -0.0225 +v 0.5441 0.7234 -0.0362 +v 0.5007 0.4954 -0.0448 +v 0.5116 0.5273 -0.0278 +v 0.5196 0.5223 -0.0099 +v 0.6141 0.4824 -0.0067 +v 0.6251 0.4559 -0.0172 +v 0.5922 0.4593 -0.0170 +v 0.6544 0.5000 0.0197 +v 0.5084 0.5956 -0.0919 +v 0.5087 0.5722 -0.0734 +v 0.4922 0.5595 -0.0925 +v 0.5285 0.4483 -0.0589 +v 0.6986 0.5752 0.0364 +v 0.7160 0.5567 0.0593 +v 0.6877 0.5382 0.0432 +v 0.5248 0.4937 -0.0115 +v 0.5480 0.4664 -0.0217 +v 0.5237 0.6857 -0.0523 +v 0.4998 0.6891 -0.0639 +v 0.5391 0.6066 -0.0361 +v 0.5629 0.6260 -0.0248 +v 0.5726 0.5943 -0.0166 +v 0.5205 0.6722 -0.0730 +v 0.5317 0.6708 -0.0760 +v 0.5198 0.6630 -0.1055 +v 0.5495 0.5184 0.0091 +v 0.5428 0.5258 0.0035 +v 0.5577 0.5312 0.0005 +v 0.5364 0.6280 -0.0500 +v 0.5238 0.6125 -0.0700 +v 0.6281 0.8636 0.0938 +v 0.6213 0.8908 0.1315 +v 0.5232 0.5884 -0.0534 +v 0.6352 0.4452 -0.0248 +v 0.6668 0.4522 -0.0132 +v 0.6867 0.4338 -0.0162 +v 0.4918 0.6432 -0.1477 +v 0.5114 0.6456 -0.1254 +v 0.5115 0.6200 -0.1179 +v 0.5553 0.2800 -0.0530 +v 0.5789 0.8055 0.0152 +v 0.5774 0.5527 -0.0012 +v 0.6946 0.5128 0.0488 +v 0.6953 0.4875 0.0281 +v 0.6793 0.4888 0.0205 +v 0.7019 0.4160 -0.0048 +v 0.6604 0.4020 -0.0352 +v 0.6497 0.4245 -0.0376 +v 0.4912 0.6765 -0.1137 +v 0.4866 0.6789 -0.1205 +v 0.4840 0.6866 -0.0884 +v 0.7115 0.4529 0.0107 +v 0.7171 0.4838 0.0400 +v 0.7369 0.4771 0.0664 +v 0.5594 0.7825 0.0073 +v 0.5439 0.7814 -0.0022 +v 0.5485 0.7852 -0.0035 +v 0.7270 0.4401 0.0327 +v 0.7415 0.5225 0.0958 +v 0.7419 0.5721 0.0907 +v 0.7620 0.5753 0.1738 +v 0.7328 0.6288 0.0872 +v 0.4875 0.6683 -0.1379 +v 0.4904 0.5846 -0.1110 +v 0.6180 0.7377 0.0042 +v 0.5643 0.5195 0.0040 +v 0.5813 0.5365 -0.0023 +v 0.4993 0.7142 -0.0598 +v 0.5151 0.9128 0.0035 +v 0.5984 0.7794 0.0184 +v 0.4892 0.6825 -0.0891 +v 0.5669 0.4936 -0.0026 +v 0.7203 0.5196 0.0686 +v 0.6533 0.4625 -0.0078 +v 0.5766 0.8444 0.0235 +v 0.5623 0.7825 0.0079 +v 0.7520 0.6314 0.1844 +v 0.5167 0.7730 -0.0406 +v 0.5400 0.6741 -0.0581 +v 0.5303 0.6776 -0.0624 +v 0.5353 0.7759 -0.0228 +v 0.6239 0.7833 0.0314 +v 0.5960 0.8909 0.0700 +v 0.6122 0.3457 -0.0448 +v 0.4938 0.5309 -0.0685 +v 0.6776 0.6411 0.0149 +v 0.5357 0.7863 -0.0175 +v 0.5982 0.4280 -0.0528 +v 0.6040 0.4038 -0.0603 +v 0.5174 0.7896 -0.0284 +v 0.7582 0.6342 0.2818 +v 0.7690 0.5736 0.2749 +v 0.4943 0.7922 -0.0363 +v 0.5854 0.5220 0.0003 +v 0.5304 0.7802 -0.0155 +v 0.5130 0.7792 -0.0265 +v 0.6597 0.8562 0.1685 +v 0.7211 0.7447 0.1787 +v 0.6912 0.8179 0.2141 +v 0.5286 0.6525 -0.1003 +v 0.5129 0.7787 -0.0275 +v 0.5682 0.7832 0.0151 +v 0.5171 0.9373 0.0194 +v 0.4939 0.7699 -0.0503 +v 0.6871 0.4657 0.0044 +v 0.6327 0.5371 0.0068 +v 0.6520 0.5319 0.0182 +v 0.6466 0.5575 0.0148 +v 0.7649 0.5192 0.1610 +v 0.4720 0.2776 -0.0588 +v 0.5948 0.4476 -0.0270 +v 0.4767 0.6883 -0.0879 +v 0.6595 0.5052 0.0319 +v 0.6627 0.5227 0.0286 +v 0.6748 0.5067 0.0376 +v 0.5094 0.5448 -0.0511 +v 0.7436 0.4215 0.0823 +v 0.5889 0.9153 0.1029 +v 0.4976 0.6930 -0.0628 +v 0.5039 0.6639 -0.1257 +v 0.5413 0.5168 0.0092 +v 0.5031 0.6686 -0.1125 +v 0.5327 0.5174 0.0054 +v 0.4791 0.6807 -0.1241 +v 0.7373 0.6903 0.1852 +v 0.7417 0.6977 0.2756 +v 0.5128 0.6674 -0.0998 +v 0.7229 0.6814 0.1002 +v 0.7119 0.7257 0.1136 +v 0.5199 0.6768 -0.0623 +v 0.5147 0.6813 -0.0562 +v 0.6730 0.5500 0.0303 +v 0.5024 0.6834 -0.0634 +v 0.7196 0.7647 0.2546 +v 0.6510 0.5129 0.0235 +v 0.2529 0.3140 0.0303 +v 0.5906 0.4839 -0.0078 +v 0.5462 0.6605 -0.0508 +v 0.4910 0.7798 -0.0353 +v 0.4916 0.7787 -0.0363 +v 0.6419 0.5178 0.0164 +v 0.1676 0.4480 0.2683 +v 0.1733 0.5065 0.2927 +v 0.1712 0.3868 0.2183 +v 0.1839 0.3363 0.1566 +v 0.2100 0.2894 0.0991 +v 0.2529 0.2528 0.0395 +v 0.3176 0.2289 -0.0116 +v 0.3888 0.2179 -0.0418 +v 0.4720 0.2164 -0.0496 +v 0.5553 0.2188 -0.0438 +v 0.6266 0.2311 -0.0158 +v 0.6914 0.2557 0.0337 +v 0.7337 0.2931 0.0920 +v 0.7595 0.3407 0.1486 +v 0.7717 0.3915 0.2101 +v 0.7744 0.4537 0.2594 +v 0.7690 0.5124 0.2841 +v 0.1676 0.3868 0.2958 +v 0.1733 0.4453 0.3202 +v 0.1712 0.3256 0.2458 +v 0.1839 0.2751 0.1841 +v 0.2100 0.2282 0.1266 +v 0.2529 0.1916 0.0670 +v 0.3176 0.1677 0.0159 +v 0.3888 0.1567 -0.0143 +v 0.4720 0.1552 -0.0221 +v 0.5553 0.1576 -0.0163 +v 0.6266 0.1699 0.0117 +v 0.6914 0.1945 0.0612 +v 0.7337 0.2319 0.1195 +v 0.7595 0.2795 0.1761 +v 0.7717 0.3303 0.2376 +v 0.7744 0.3925 0.2869 +v 0.7690 0.4512 0.3116 + +vt 0.0147 0.4668 0.0000 +vt 0.1049 0.4716 0.0000 +vt 0.1292 0.5313 0.0000 +vt 0.5005 0.2458 0.0000 +vt 0.5005 0.2570 0.0000 +vt 0.4745 0.2628 0.0000 +vt 0.3859 0.4818 0.0000 +vt 0.3646 0.4669 0.0000 +vt 0.3693 0.4471 0.0000 +vt 0.4759 0.2479 0.0000 +vt 0.4423 0.2555 0.0000 +vt 0.4120 0.4846 0.0000 +vt 0.3932 0.4639 0.0000 +vt 0.4003 0.4442 0.0000 +vt 0.2789 0.6680 0.0000 +vt 0.3509 0.6923 0.0000 +vt 0.3233 0.7432 0.0000 +vt 0.5005 0.0338 0.0000 +vt 0.4441 0.0397 0.0000 +vt 0.4312 0.0048 0.0000 +vt 0.2866 0.4184 0.0000 +vt 0.2814 0.3609 0.0000 +vt 0.3366 0.3971 0.0000 +vt 0.4479 0.2441 0.0000 +vt 0.4187 0.2424 0.0000 +vt 0.5013 0.6285 0.0000 +vt 0.5009 0.7040 0.0000 +vt 0.4227 0.7019 0.0000 +vt 0.4367 0.3599 0.0000 +vt 0.4546 0.3734 0.0000 +vt 0.4474 0.3880 0.0000 +vt 0.4127 0.1154 0.0000 +vt 0.3776 0.1397 0.0000 +vt 0.3570 0.1118 0.0000 +vt 0.4245 0.2358 0.0000 +vt 0.3990 0.2257 0.0000 +vt 0.4291 0.2176 0.0000 +vt 0.4278 0.2257 0.0000 +vt 0.4085 0.2183 0.0000 +vt 0.3920 0.2671 0.0000 +vt 0.3702 0.2432 0.0000 +vt 0.3340 0.4539 0.0000 +vt 0.2997 0.4488 0.0000 +vt 0.3483 0.1726 0.0000 +vt 0.3277 0.2091 0.0000 +vt 0.2881 0.2020 0.0000 +vt 0.4647 0.1244 0.0000 +vt 0.5005 0.1223 0.0000 +vt 0.5005 0.1584 0.0000 +vt 0.3882 0.2060 0.0000 +vt 0.3842 0.2055 0.0000 +vt 0.4009 0.1949 0.0000 +vt 0.3240 0.5332 0.0000 +vt 0.3086 0.5596 0.0000 +vt 0.2893 0.5442 0.0000 +vt 0.3901 0.5544 0.0000 +vt 0.3855 0.5335 0.0000 +vt 0.3961 0.5202 0.0000 +vt 0.4023 0.1612 0.0000 +vt 0.2419 0.1475 0.0000 +vt 0.2356 0.2274 0.0000 +vt 0.3833 0.3293 0.0000 +vt 0.4165 0.2829 0.0000 +vt 0.4238 0.3222 0.0000 +vt 0.1094 0.6010 0.0000 +vt 0.1699 0.5849 0.0000 +vt 0.2225 0.6315 0.0000 +vt 0.4860 0.4115 0.0000 +vt 0.4924 0.3854 0.0000 +vt 0.5012 0.3858 0.0000 +vt 0.3136 0.4853 0.0000 +vt 0.3135 0.4704 0.0000 +vt 0.3372 0.4740 0.0000 +vt 0.4066 0.2006 0.0000 +vt 0.4228 0.1832 0.0000 +vt 0.3239 0.3285 0.0000 +vt 0.2580 0.2993 0.0000 +vt 0.4569 0.0982 0.0000 +vt 0.5005 0.0934 0.0000 +vt 0.4319 0.1411 0.0000 +vt 0.4280 0.1927 0.0000 +vt 0.4470 0.1698 0.0000 +vt 0.4744 0.1790 0.0000 +vt 0.4737 0.1615 0.0000 +vt 0.3593 0.2991 0.0000 +vt 0.3583 0.3638 0.0000 +vt 0.3901 0.0568 0.0000 +vt 0.4604 0.5378 0.0000 +vt 0.4215 0.5338 0.0000 +vt 0.4193 0.5091 0.0000 +vt 0.3461 0.5423 0.0000 +vt 0.3661 0.5430 0.0000 +vt 0.3662 0.5686 0.0000 +vt 0.2731 0.5238 0.0000 +vt 0.2948 0.5106 0.0000 +vt 0.3067 0.5212 0.0000 +vt 0.4582 0.4314 0.0000 +vt 0.4820 0.4394 0.0000 +vt 0.4781 0.4654 0.0000 +vt 0.1687 0.6591 0.0000 +vt 0.5006 0.5393 0.0000 +vt 0.5005 0.5826 0.0000 +vt 0.2482 0.4258 0.0000 +vt 0.2699 0.4542 0.0000 +vt 0.2515 0.4650 0.0000 +vt 0.4436 0.5938 0.0000 +vt 0.4655 0.3097 0.0000 +vt 0.4596 0.3179 0.0000 +vt 0.4055 0.4116 0.0000 +vt 0.3746 0.4209 0.0000 +vt 0.4472 0.3421 0.0000 +vt 0.4638 0.3541 0.0000 +vt 0.4621 0.3644 0.0000 +vt 0.3851 0.5111 0.0000 +vt 0.3696 0.5043 0.0000 +vt 0.3786 0.4937 0.0000 +vt 0.4170 0.3941 0.0000 +vt 0.4310 0.3714 0.0000 +vt 0.1987 0.1072 0.0000 +vt 0.2659 0.0727 0.0000 +vt 0.4255 0.4356 0.0000 +vt 0.3309 0.5828 0.0000 +vt 0.3224 0.6075 0.0000 +vt 0.2824 0.5897 0.0000 +vt 0.4691 0.4044 0.0000 +vt 0.3374 0.0828 0.0000 +vt 0.3767 0.1817 0.0000 +vt 0.3352 0.4294 0.0000 +vt 0.2436 0.4922 0.0000 +vt 0.2667 0.4989 0.0000 +vt 0.2640 0.6037 0.0000 +vt 0.4861 0.3510 0.0000 +vt 0.4776 0.3328 0.0000 +vt 0.4828 0.3273 0.0000 +vt 0.2509 0.5633 0.0000 +vt 0.2244 0.5712 0.0000 +vt 0.1957 0.5278 0.0000 +vt 0.3952 0.2075 0.0000 +vt 0.3920 0.2069 0.0000 +vt 0.4106 0.2053 0.0000 +vt 0.1759 0.4752 0.0000 +vt 0.1009 0.4117 0.0000 +vt 0.1954 0.3660 0.0000 +vt 0.2214 0.4448 0.0000 +vt 0.4894 0.3650 0.0000 +vt 0.4963 0.3512 0.0000 +vt 0.5013 0.3506 0.0000 +vt 0.3407 0.2632 0.0000 +vt 0.3509 0.4949 0.0000 +vt 0.3596 0.4824 0.0000 +vt 0.4679 0.2897 0.0000 +vt 0.4512 0.0662 0.0000 +vt 0.3857 0.3856 0.0000 +vt 0.3562 0.2113 0.0000 +vt 0.4558 0.3242 0.0000 +vt 0.2113 0.4830 0.0000 +vt 0.2544 0.5237 0.0000 +vt 0.3366 0.5693 0.0000 +vt 0.3182 0.1465 0.0000 +vt 0.2735 0.5527 0.0000 +vt 0.1012 0.3494 0.0000 +vt 0.1847 0.4235 0.0000 +vt 0.4508 0.2318 0.0000 +vt 0.4757 0.2315 0.0000 +vt 0.4010 0.3544 0.0000 +vt 0.4301 0.3460 0.0000 +vt 0.4367 0.3271 0.0000 +vt 0.4212 0.3580 0.0000 +vt 0.3021 0.2818 0.0000 +vt 0.4032 0.2219 0.0000 +vt 0.2912 0.1118 0.0000 +vt 0.3179 0.0469 0.0000 +vt 0.3723 0.0264 0.0000 +vt 0.3117 0.6281 0.0000 +vt 0.3711 0.6357 0.0000 +vt 0.4738 0.4975 0.0000 +vt 0.5008 0.5007 0.0000 +vt 0.1975 0.3082 0.0000 +vt 0.3746 0.6135 0.0000 +vt 0.4366 0.6327 0.0000 +vt 0.4299 0.2024 0.0000 +vt 0.4496 0.1861 0.0000 +vt 0.0053 0.3348 0.0000 +vt 0.5005 0.1954 0.0000 +vt 0.4749 0.1968 0.0000 +vt 0.5005 0.2115 0.0000 +vt 0.4768 0.2107 0.0000 +vt 0.3319 0.4878 0.0000 +vt 0.4328 0.2102 0.0000 +vt 0.4508 0.2000 0.0000 +vt 0.4135 0.2110 0.0000 +vt 0.1895 0.1824 0.0000 +vt 0.1298 0.1429 0.0000 +vt 0.1384 0.2290 0.0000 +vt 0.0685 0.1945 0.0000 +vt 0.4418 0.3514 0.0000 +vt 0.4494 0.2171 0.0000 +vt 0.5009 0.4400 0.0000 +vt 0.5005 0.0619 0.0000 +vt 0.4742 0.2157 0.0000 +vt 0.3008 0.4876 0.0000 +vt 0.2923 0.4722 0.0000 +vt 0.0005 0.4015 0.0000 +vt 0.4068 0.7707 0.0000 +vt 0.4363 0.3405 0.0000 +vt 0.4123 0.2121 0.0000 +vt 0.3686 0.5816 0.0000 +vt 0.4912 0.3214 0.0000 +vt 0.4097 0.5625 0.0000 +vt 0.5005 0.4679 0.0000 +vt 0.2791 0.4819 0.0000 +vt 0.2919 0.4918 0.0000 +vt 0.2827 0.4994 0.0000 +vt 0.4738 0.3832 0.0000 +vt 0.4791 0.3668 0.0000 +vt 0.4334 0.5056 0.0000 +vt 0.0543 0.5378 0.0000 +vt 0.4456 0.4851 0.0000 +vt 0.4515 0.4542 0.0000 +vt 0.5005 0.3015 0.0000 +vt 0.4916 0.3521 0.0000 +vt 0.5008 0.2886 0.0000 +vt 0.5005 0.2309 0.0000 +vt 0.5005 0.2127 0.0000 +vt 0.4341 0.4127 0.0000 +vt 0.3949 0.5126 0.0000 +vt 0.3922 0.5039 0.0000 +vt 0.4020 0.5117 0.0000 +vt 0.4750 0.3572 0.0000 +vt 0.4057 0.5296 0.0000 +vt 0.4019 0.0857 0.0000 +vt 0.4541 0.2102 0.0000 +vt 0.0273 0.2648 0.0000 +vt 0.1148 0.2863 0.0000 +vt 0.5011 0.3651 0.0000 +vt 0.1987 0.2586 0.0000 +vt 0.4424 0.3354 0.0000 +vt 0.5008 0.3208 0.0000 +vt 0.4437 0.3275 0.0000 +vt 0.2981 0.5717 0.0000 +vt 0.4023 0.4956 0.0000 +vt 0.4203 0.4658 0.0000 +vt 0.2287 0.5259 0.0000 +vt 0.9848 0.4692 0.0000 +vt 0.9459 0.5412 0.0000 +vt 0.8720 0.5338 0.0000 +vt 0.5265 0.2472 0.0000 +vt 0.5278 0.2623 0.0000 +vt 0.6153 0.4824 0.0000 +vt 0.6078 0.4648 0.0000 +vt 0.6324 0.4475 0.0000 +vt 0.5545 0.2426 0.0000 +vt 0.5596 0.2542 0.0000 +vt 0.5894 0.4851 0.0000 +vt 0.5805 0.4662 0.0000 +vt 0.6005 0.4447 0.0000 +vt 0.5981 0.4959 0.0000 +vt 0.7226 0.6706 0.0000 +vt 0.7602 0.7091 0.0000 +vt 0.6771 0.7445 0.0000 +vt 0.5005 0.0005 0.0000 +vt 0.5712 0.0054 0.0000 +vt 0.7164 0.4194 0.0000 +vt 0.6676 0.4301 0.0000 +vt 0.6652 0.3982 0.0000 +vt 0.5782 0.2337 0.0000 +vt 0.5835 0.2407 0.0000 +vt 0.5670 0.6338 0.0000 +vt 0.5793 0.7023 0.0000 +vt 0.5645 0.3606 0.0000 +vt 0.5700 0.3722 0.0000 +vt 0.5539 0.3888 0.0000 +vt 0.5906 0.1168 0.0000 +vt 0.6014 0.0873 0.0000 +vt 0.6464 0.1140 0.0000 +vt 0.5984 0.2198 0.0000 +vt 0.6026 0.2235 0.0000 +vt 0.5728 0.2157 0.0000 +vt 0.5891 0.2097 0.0000 +vt 0.5936 0.2159 0.0000 +vt 0.6318 0.2428 0.0000 +vt 0.6677 0.4541 0.0000 +vt 0.6550 0.1736 0.0000 +vt 0.6842 0.1482 0.0000 +vt 0.7142 0.2035 0.0000 +vt 0.5379 0.1252 0.0000 +vt 0.5294 0.1616 0.0000 +vt 0.6140 0.2039 0.0000 +vt 0.5958 0.1986 0.0000 +vt 0.6018 0.1939 0.0000 +vt 0.6771 0.5351 0.0000 +vt 0.6938 0.5232 0.0000 +vt 0.7137 0.5456 0.0000 +vt 0.6110 0.5558 0.0000 +vt 0.5943 0.5303 0.0000 +vt 0.6034 0.5215 0.0000 +vt 0.6001 0.1616 0.0000 +vt 0.5710 0.1421 0.0000 +vt 0.7597 0.1494 0.0000 +vt 0.8115 0.1846 0.0000 +vt 0.7662 0.2292 0.0000 +vt 0.6177 0.3301 0.0000 +vt 0.5999 0.3550 0.0000 +vt 0.5771 0.3224 0.0000 +vt 0.8905 0.6045 0.0000 +vt 0.8310 0.6625 0.0000 +vt 0.7787 0.6346 0.0000 +vt 0.5151 0.4121 0.0000 +vt 0.5009 0.4119 0.0000 +vt 0.6876 0.4855 0.0000 +vt 0.6697 0.4878 0.0000 +vt 0.6640 0.4736 0.0000 +vt 0.5748 0.1915 0.0000 +vt 0.5804 0.1824 0.0000 +vt 0.6785 0.3296 0.0000 +vt 0.7003 0.2837 0.0000 +vt 0.7442 0.3013 0.0000 +vt 0.5459 0.0983 0.0000 +vt 0.5564 0.1701 0.0000 +vt 0.5539 0.1850 0.0000 +vt 0.5284 0.1787 0.0000 +vt 0.5005 0.1772 0.0000 +vt 0.6430 0.3002 0.0000 +vt 0.6430 0.3646 0.0000 +vt 0.6303 0.0280 0.0000 +vt 0.6132 0.0590 0.0000 +vt 0.6097 0.2674 0.0000 +vt 0.5849 0.2832 0.0000 +vt 0.5402 0.5378 0.0000 +vt 0.5678 0.5055 0.0000 +vt 0.5815 0.5092 0.0000 +vt 0.6558 0.5438 0.0000 +vt 0.6657 0.5712 0.0000 +vt 0.6354 0.5697 0.0000 +vt 0.7059 0.5124 0.0000 +vt 0.5430 0.4322 0.0000 +vt 0.5497 0.4544 0.0000 +vt 0.5233 0.4656 0.0000 +vt 0.5587 0.5950 0.0000 +vt 0.7543 0.4271 0.0000 +vt 0.7807 0.4461 0.0000 +vt 0.7504 0.4667 0.0000 +vt 0.5788 0.5343 0.0000 +vt 0.5917 0.5639 0.0000 +vt 0.5647 0.3278 0.0000 +vt 0.5418 0.3174 0.0000 +vt 0.5956 0.4123 0.0000 +vt 0.6156 0.3864 0.0000 +vt 0.6264 0.4223 0.0000 +vt 0.5542 0.3419 0.0000 +vt 0.5591 0.3514 0.0000 +vt 0.5393 0.3648 0.0000 +vt 0.6157 0.5115 0.0000 +vt 0.6086 0.5039 0.0000 +vt 0.6221 0.4943 0.0000 +vt 0.5841 0.3948 0.0000 +vt 0.5672 0.4138 0.0000 +vt 0.7110 0.1141 0.0000 +vt 0.7358 0.0748 0.0000 +vt 0.5756 0.4364 0.0000 +vt 0.6724 0.5841 0.0000 +vt 0.7053 0.5733 0.0000 +vt 0.7220 0.5927 0.0000 +vt 0.5098 0.3851 0.0000 +vt 0.5277 0.3835 0.0000 +vt 0.5323 0.4048 0.0000 +vt 0.5945 0.7713 0.0000 +vt 0.6251 0.1815 0.0000 +vt 0.6365 0.4674 0.0000 +vt 0.7583 0.4933 0.0000 +vt 0.7484 0.5253 0.0000 +vt 0.7302 0.5250 0.0000 +vt 0.7398 0.6069 0.0000 +vt 0.6925 0.6304 0.0000 +vt 0.6819 0.6101 0.0000 +vt 0.5160 0.3506 0.0000 +vt 0.5102 0.3521 0.0000 +vt 0.5188 0.3269 0.0000 +vt 0.7529 0.5667 0.0000 +vt 0.7737 0.5282 0.0000 +vt 0.8066 0.5304 0.0000 +vt 0.6068 0.2054 0.0000 +vt 0.5889 0.2094 0.0000 +vt 0.5914 0.2039 0.0000 +vt 0.7790 0.5747 0.0000 +vt 0.8264 0.4776 0.0000 +vt 0.8176 0.4259 0.0000 +vt 0.8998 0.4138 0.0000 +vt 0.8059 0.3678 0.0000 +vt 0.5123 0.3651 0.0000 +vt 0.5195 0.4396 0.0000 +vt 0.6613 0.2639 0.0000 +vt 0.6307 0.5044 0.0000 +vt 0.6418 0.4822 0.0000 +vt 0.5337 0.2895 0.0000 +vt 0.5524 0.0668 0.0000 +vt 0.6458 0.2115 0.0000 +vt 0.5245 0.3325 0.0000 +vt 0.6141 0.5347 0.0000 +vt 0.7909 0.4849 0.0000 +vt 0.6941 0.5613 0.0000 +vt 0.6256 0.1415 0.0000 +vt 0.6096 0.2049 0.0000 +vt 0.9000 0.3524 0.0000 +vt 0.5515 0.2303 0.0000 +vt 0.5709 0.3469 0.0000 +vt 0.5645 0.3412 0.0000 +vt 0.5747 0.2240 0.0000 +vt 0.6746 0.2107 0.0000 +vt 0.6652 0.0847 0.0000 +vt 0.6511 0.6939 0.0000 +vt 0.5274 0.4979 0.0000 +vt 0.7207 0.3628 0.0000 +vt 0.5729 0.2018 0.0000 +vt 0.6289 0.6150 0.0000 +vt 0.6339 0.6380 0.0000 +vt 0.5520 0.1991 0.0000 +vt 0.9949 0.3369 0.0000 +vt 0.9995 0.4038 0.0000 +vt 0.5281 0.1971 0.0000 +vt 0.6494 0.4952 0.0000 +vt 0.5698 0.2093 0.0000 +vt 0.5491 0.2099 0.0000 +vt 0.8023 0.1093 0.0000 +vt 0.8624 0.2316 0.0000 +vt 0.8703 0.1449 0.0000 +vt 0.5467 0.3737 0.0000 +vt 0.5529 0.2158 0.0000 +vt 0.6173 0.2034 0.0000 +vt 0.5588 0.0402 0.0000 +vt 0.5267 0.2312 0.0000 +vt 0.7295 0.5547 0.0000 +vt 0.6883 0.4705 0.0000 +vt 0.7097 0.4730 0.0000 +vt 0.7023 0.4497 0.0000 +vt 0.8959 0.4739 0.0000 +vt 0.5005 0.7724 0.0000 +vt 0.6340 0.5832 0.0000 +vt 0.5103 0.3214 0.0000 +vt 0.7183 0.5004 0.0000 +vt 0.7223 0.4825 0.0000 +vt 0.7349 0.4997 0.0000 +vt 0.5555 0.4858 0.0000 +vt 0.8313 0.5881 0.0000 +vt 0.6843 0.0486 0.0000 +vt 0.5357 0.3096 0.0000 +vt 0.5225 0.3673 0.0000 +vt 0.6052 0.5128 0.0000 +vt 0.5262 0.3575 0.0000 +vt 0.5981 0.5120 0.0000 +vt 0.5059 0.3513 0.0000 +vt 0.8860 0.2886 0.0000 +vt 0.9734 0.2673 0.0000 +vt 0.5380 0.3550 0.0000 +vt 0.8040 0.3108 0.0000 +vt 0.8029 0.2613 0.0000 +vt 0.5581 0.3352 0.0000 +vt 0.5573 0.3283 0.0000 +vt 0.7323 0.4549 0.0000 +vt 0.5458 0.3240 0.0000 +vt 0.9322 0.1972 0.0000 +vt 0.7099 0.4918 0.0000 +vt 0.2399 0.7066 0.0000 +vt 0.6343 0.5445 0.0000 +vt 0.5798 0.3590 0.0000 +vt 0.5256 0.2097 0.0000 +vt 0.5282 0.2152 0.0000 +vt 0.7007 0.4875 0.0000 +vt 0.0147 0.5768 0.0000 +vt 0.0005 0.5115 0.0000 +vt 0.0543 0.6478 0.0000 +vt 0.1094 0.7110 0.0000 +vt 0.1687 0.7691 0.0000 +vt 0.2399 0.8166 0.0000 +vt 0.3233 0.8532 0.0000 +vt 0.4068 0.8807 0.0000 +vt 0.5005 0.8824 0.0000 +vt 0.5945 0.8813 0.0000 +vt 0.6771 0.8545 0.0000 +vt 0.7602 0.8191 0.0000 +vt 0.8310 0.7725 0.0000 +vt 0.8905 0.7145 0.0000 +vt 0.9459 0.6512 0.0000 +vt 0.9848 0.5792 0.0000 +vt 0.9995 0.5138 0.0000 +vt 0.0147 0.6868 0.0000 +vt 0.0005 0.6215 0.0000 +vt 0.0543 0.7578 0.0000 +vt 0.1094 0.8210 0.0000 +vt 0.1687 0.8791 0.0000 +vt 0.2399 0.9266 0.0000 +vt 0.3233 0.9632 0.0000 +vt 0.4068 0.9907 0.0000 +vt 0.5005 0.9924 0.0000 +vt 0.5945 0.9913 0.0000 +vt 0.6771 0.9645 0.0000 +vt 0.7602 0.9291 0.0000 +vt 0.8310 0.8825 0.0000 +vt 0.8905 0.8245 0.0000 +vt 0.9459 0.7612 0.0000 +vt 0.9848 0.6892 0.0000 +vt 0.9995 0.6238 0.0000 + +vn -0.9892 0.0918 -0.1146 +vn -0.9788 0.0236 -0.2033 +vn -0.9677 -0.0121 -0.2518 +vn -0.0286 0.4641 -0.8853 +vn -0.0210 0.1059 -0.9942 +vn -0.2963 0.0263 -0.9547 +vn -0.2656 -0.3737 -0.8887 +vn -0.1333 -0.1062 -0.9854 +vn -0.2982 -0.3067 -0.9039 +vn -0.2701 0.4062 -0.8730 +vn -0.5118 0.1804 -0.8400 +vn -0.6858 -0.4508 -0.5714 +vn -0.4596 -0.4367 -0.7734 +vn -0.6024 -0.3459 -0.7194 +vn -0.6700 -0.2574 -0.6963 +vn -0.3874 -0.2160 -0.8962 +vn -0.4873 -0.2184 -0.8455 +vn -0.0187 0.7636 -0.6454 +vn -0.3895 0.6894 -0.6107 +vn -0.3730 0.8476 -0.3773 +vn -0.4425 -0.2135 -0.8710 +vn -0.6390 0.0497 -0.7676 +vn -0.3241 -0.1838 -0.9280 +vn -0.4361 0.4943 -0.7520 +vn -0.5509 0.4800 -0.6827 +vn -0.0096 0.1041 -0.9945 +vn -0.0117 -0.1221 -0.9924 +vn -0.2092 -0.1327 -0.9688 +vn -0.9011 0.2674 -0.3415 +vn -0.8776 0.0591 -0.4757 +vn -0.8804 -0.3287 -0.3418 +vn -0.5055 0.2486 -0.8262 +vn -0.5902 0.2855 -0.7551 +vn -0.6930 0.3322 -0.6398 +vn -0.4684 0.6694 -0.5766 +vn -0.4272 0.7368 -0.5240 +vn -0.2852 0.8727 -0.3964 +vn -0.3535 0.8216 -0.4473 +vn -0.3118 0.8767 -0.3662 +vn -0.5250 0.1467 -0.8384 +vn -0.4721 0.4437 -0.7617 +vn -0.2451 -0.0267 -0.9691 +vn -0.4187 -0.1407 -0.8972 +vn -0.5714 0.2908 -0.7675 +vn -0.5276 0.3879 -0.7558 +vn -0.7228 0.4014 -0.5625 +vn -0.1836 0.4449 -0.8765 +vn -0.0125 0.4693 -0.8829 +vn -0.0217 0.5490 -0.8355 +vn -0.7483 0.2841 -0.5994 +vn -0.4508 0.3894 -0.8032 +vn -0.7218 -0.1978 -0.6632 +vn -0.2589 0.4773 -0.8397 +vn -0.1985 0.5505 -0.8109 +vn -0.3127 0.5807 -0.7516 +vn -0.1325 0.5499 -0.8246 +vn 0.0988 0.3107 -0.9454 +vn -0.0383 0.4255 -0.9042 +vn -0.5889 0.2725 -0.7609 +vn -0.8103 0.4772 -0.3402 +vn -0.8348 0.3692 -0.4084 +vn -0.3030 -0.0161 -0.9529 +vn -0.4987 -0.0940 -0.8617 +vn -0.6857 0.2014 -0.6994 +vn -0.9601 -0.0063 -0.2796 +vn -0.9401 -0.0814 -0.3311 +vn -0.8443 -0.2348 -0.4818 +vn -0.5192 -0.4575 -0.7219 +vn -0.4560 -0.0053 -0.8899 +vn -0.0145 0.0191 -0.9997 +vn -0.4007 -0.1577 -0.9025 +vn -0.3961 -0.0224 -0.9179 +vn -0.1931 0.0337 -0.9806 +vn -0.6352 -0.3880 -0.6678 +vn -0.6957 0.1472 -0.7031 +vn -0.4450 0.1127 -0.8884 +vn -0.7920 0.2538 -0.5553 +vn -0.2588 0.1393 -0.9558 +vn -0.0160 0.0757 -0.9970 +vn -0.4640 0.3737 -0.8031 +vn -0.5965 -0.2402 -0.7659 +vn -0.5234 0.3510 -0.7764 +vn -0.2373 0.0020 -0.9714 +vn -0.2813 0.4791 -0.8315 +vn -0.3584 0.0892 -0.9293 +vn -0.2542 0.0002 -0.9671 +vn -0.6701 0.5630 -0.4837 +vn -0.7034 0.1121 -0.7019 +vn -0.6507 0.4083 -0.6402 +vn -0.7793 -0.1925 -0.5964 +vn -0.1515 0.3979 -0.9048 +vn -0.0209 0.3518 -0.9359 +vn -0.1058 0.5639 -0.8190 +vn -0.3450 0.6540 -0.6732 +vn -0.3752 0.7249 -0.5777 +vn -0.3356 0.6076 -0.7198 +vn -0.8198 -0.4081 -0.4018 +vn -0.6040 -0.5115 -0.6112 +vn -0.6003 -0.4769 -0.6420 +vn -0.8971 -0.1474 -0.4166 +vn -0.0088 -0.1756 -0.9844 +vn -0.0130 0.2566 -0.9664 +vn -0.6727 -0.1461 -0.7253 +vn -0.5253 -0.1978 -0.8276 +vn -0.5550 -0.1543 -0.8174 +vn -0.2962 0.5043 -0.8111 +vn -0.5151 0.3789 -0.7689 +vn -0.6769 0.4352 -0.5936 +vn -0.7119 -0.1376 -0.6887 +vn -0.3869 -0.2729 -0.8808 +vn -0.2593 0.9100 -0.3235 +vn -0.4232 0.8725 -0.2441 +vn -0.6388 0.6348 -0.4346 +vn 0.0075 -0.5272 -0.8497 +vn 0.1431 -0.3278 -0.9338 +vn 0.0417 -0.2968 -0.9540 +vn -0.9190 -0.2914 -0.2656 +vn -0.9525 -0.1975 -0.2320 +vn -0.8218 0.5259 -0.2193 +vn -0.7717 0.5717 -0.2788 +vn -0.8407 -0.2471 -0.4819 +vn -0.1589 0.6204 -0.7680 +vn -0.3844 0.3934 -0.8351 +vn -0.5135 0.2291 -0.8270 +vn -0.7775 -0.3931 -0.4910 +vn -0.7590 0.4870 -0.4321 +vn -0.5333 0.0772 -0.8424 +vn -0.2512 -0.2327 -0.9396 +vn -0.5037 0.2809 -0.8169 +vn -0.3684 0.3409 -0.8649 +vn -0.7436 -0.0832 -0.6634 +vn -0.6117 0.7847 -0.1002 +vn -0.5291 0.8080 -0.2592 +vn -0.4508 0.8443 -0.2898 +vn -0.6923 0.3110 -0.6511 +vn -0.8890 -0.0214 -0.4573 +vn -0.8997 0.1327 -0.4158 +vn -0.2615 0.0617 -0.9632 +vn -0.7042 -0.3851 -0.5965 +vn -0.4049 -0.7183 -0.5658 +vn -0.8981 0.0608 -0.4355 +vn -0.9788 0.1245 -0.1626 +vn -0.9079 0.1364 -0.3963 +vn -0.7298 -0.0858 -0.6783 +vn -0.4109 0.5683 -0.7129 +vn -0.2760 0.8715 -0.4054 +vn -0.0052 0.8916 -0.4528 +vn -0.4766 0.3068 -0.8238 +vn 0.0050 -0.1775 -0.9841 +vn -0.0091 -0.0562 -0.9984 +vn -0.3366 0.0198 -0.9414 +vn -0.3670 0.2717 -0.8897 +vn -0.3339 0.0046 -0.9426 +vn -0.3391 0.4495 -0.8264 +vn -0.6108 0.5190 -0.5979 +vn -0.7075 0.1706 -0.6858 +vn -0.4370 0.5756 -0.6911 +vn -0.1373 0.5563 -0.8196 +vn -0.6839 0.4104 -0.6032 +vn -0.4112 0.5547 -0.7234 +vn -0.9719 0.1950 -0.1316 +vn -0.8965 0.0314 -0.4419 +vn -0.3061 0.7640 -0.5679 +vn -0.2095 0.7295 -0.6511 +vn -0.6765 0.0404 -0.7353 +vn -0.7748 0.5551 -0.3026 +vn -0.3352 0.8062 -0.4875 +vn -0.9828 0.0737 -0.1690 +vn -0.6294 0.2746 -0.7270 +vn -0.4010 0.7990 -0.4481 +vn -0.7680 0.5065 -0.3919 +vn -0.7313 0.6102 -0.3048 +vn -0.6386 0.7024 -0.3143 +vn -0.5403 -0.0661 -0.8389 +vn -0.2972 0.0398 -0.9540 +vn -0.6776 -0.4136 -0.6081 +vn -0.0027 -0.5203 -0.8540 +vn -0.9184 0.2515 -0.3056 +vn -0.2748 0.5707 -0.7738 +vn -0.1584 0.1286 -0.9790 +vn -0.4616 -0.5618 -0.6866 +vn -0.4293 -0.0927 -0.8984 +vn -0.9793 0.1926 -0.0624 +vn -0.0161 -0.1523 -0.9882 +vn -0.2259 -0.2227 -0.9484 +vn -0.0197 -0.0720 -0.9972 +vn -0.2632 -0.1251 -0.9566 +vn -0.2093 -0.1177 -0.9707 +vn -0.4462 -0.5951 -0.6684 +vn -0.3734 -0.3688 -0.8512 +vn -0.4127 -0.7924 -0.4493 +vn -0.8775 0.4155 -0.2396 +vn -0.8941 0.4319 -0.1185 +vn -0.9429 0.3025 -0.1392 +vn -0.9468 0.3122 -0.0776 +vn -0.4967 0.7780 -0.3847 +vn -0.2129 0.8951 -0.3917 +vn -0.0010 -0.6457 -0.7636 +vn -0.0191 0.3220 -0.9466 +vn -0.2007 0.8540 -0.4801 +vn -0.5261 -0.2296 -0.8189 +vn -0.5469 -0.1438 -0.8248 +vn -0.9882 0.1379 -0.0665 +vn -0.2607 -0.1418 -0.9549 +vn -0.3010 0.8206 -0.4858 +vn -0.2486 0.9237 -0.2915 +vn -0.1986 0.7334 -0.6502 +vn -0.2171 0.9455 -0.2426 +vn -0.3870 0.6895 -0.6122 +vn -0.0087 -0.5839 -0.8117 +vn -0.5436 -0.1897 -0.8176 +vn -0.5570 -0.2589 -0.7891 +vn -0.4501 0.2685 -0.8516 +vn -0.7925 0.0362 -0.6087 +vn -0.6696 0.5211 -0.5292 +vn -0.8579 -0.2632 -0.4412 +vn -0.9774 0.0665 -0.2005 +vn -0.8059 -0.4189 -0.4185 +vn -0.8334 -0.3312 -0.4425 +vn -0.0113 0.7507 -0.6605 +vn -0.5000 0.8023 -0.3261 +vn -0.0179 0.1168 -0.9930 +vn -0.0280 0.7348 -0.6777 +vn -0.0341 0.8515 -0.5232 +vn -0.8728 -0.3807 -0.3053 +vn -0.2925 -0.1250 -0.9481 +vn -0.2521 -0.4913 -0.8337 +vn -0.5752 -0.1476 -0.8046 +vn -0.5558 0.7877 -0.2655 +vn -0.3244 0.4596 -0.8268 +vn -0.6118 0.2479 -0.7511 +vn -0.3883 -0.3420 -0.8557 +vn -0.9704 0.2327 -0.0645 +vn -0.9662 0.2260 -0.1243 +vn -0.0165 0.5612 -0.8275 +vn -0.8997 0.3056 -0.3117 +vn -0.1538 0.8423 -0.5165 +vn 0.0106 0.9761 -0.2172 +vn -0.4197 0.4256 -0.8017 +vn -0.2580 0.5206 -0.8139 +vn -0.5099 -0.4374 -0.7407 +vn -0.7786 -0.4123 -0.4731 +vn -0.6680 0.4185 -0.6154 +vn 0.9885 0.0946 -0.1177 +vn 0.9766 0.0763 -0.2009 +vn 0.9707 -0.0059 -0.2403 +vn 0.2175 0.4167 -0.8827 +vn 0.2655 0.0332 -0.9635 +vn 0.2465 -0.3758 -0.8933 +vn 0.4508 -0.4321 -0.7811 +vn 0.2787 -0.3017 -0.9118 +vn 0.3870 0.4936 -0.7788 +vn 0.4777 0.1827 -0.8593 +vn 0.6807 -0.4529 -0.5758 +vn 0.7749 -0.3960 -0.4927 +vn 0.5928 -0.3359 -0.7320 +vn 0.5041 -0.4457 -0.7397 +vn 0.6609 -0.2685 -0.7009 +vn 0.7711 -0.1906 -0.6075 +vn 0.4693 -0.2150 -0.8565 +vn -0.0176 0.9138 -0.4057 +vn 0.3385 0.8619 -0.3777 +vn 0.4241 -0.2022 -0.8827 +vn 0.2284 -0.2246 -0.9473 +vn 0.3009 -0.1708 -0.9382 +vn 0.4152 0.6914 -0.5913 +vn 0.5263 0.4569 -0.7171 +vn 0.1372 0.1315 -0.9818 +vn 0.1889 -0.1299 -0.9734 +vn 0.8941 0.2902 -0.3410 +vn 0.9565 -0.1796 -0.2300 +vn 0.8827 -0.3064 -0.3563 +vn 0.4749 0.2725 -0.8368 +vn 0.5803 0.2684 -0.7689 +vn 0.6698 0.3602 -0.6493 +vn 0.3502 0.8087 -0.4726 +vn 0.3789 0.7560 -0.5337 +vn 0.1939 0.9029 -0.3835 +vn 0.0992 0.9694 -0.2244 +vn 0.2482 0.8870 -0.3894 +vn 0.4589 0.4349 -0.7748 +vn 0.2199 -0.0208 -0.9753 +vn 0.5447 0.3217 -0.7745 +vn 0.6608 0.4456 -0.6039 +vn 0.7042 0.4225 -0.5706 +vn 0.1420 0.4548 -0.8792 +vn 0.2331 0.5063 -0.8303 +vn 0.8500 -0.0556 -0.5238 +vn 0.6186 -0.3893 -0.6824 +vn 0.7050 -0.2003 -0.6803 +vn 0.2278 0.4733 -0.8510 +vn 0.3290 0.5971 -0.7316 +vn 0.2896 0.5777 -0.7632 +vn 0.1057 0.5527 -0.8267 +vn 0.2923 0.4695 -0.8331 +vn 0.0250 0.4179 -0.9081 +vn 0.5611 0.3112 -0.7670 +vn 0.4233 0.4058 -0.8100 +vn 0.7948 0.5049 -0.3366 +vn 0.8680 0.4384 -0.2332 +vn 0.8266 0.3904 -0.4053 +vn 0.2732 -0.0165 -0.9618 +vn 0.6635 0.0658 -0.7453 +vn 0.6643 0.2138 -0.7162 +vn 0.9600 -0.0003 -0.2800 +vn 0.8960 -0.1414 -0.4210 +vn 0.8452 -0.2504 -0.4722 +vn 0.5089 -0.4481 -0.7350 +vn -0.0089 -0.4314 -0.9021 +vn 0.3708 -0.1626 -0.9144 +vn 0.1925 -0.1126 -0.9748 +vn 0.1658 0.0472 -0.9850 +vn 0.5831 -0.2210 -0.7818 +vn 0.6667 0.1757 -0.7243 +vn 0.4231 0.1187 -0.8983 +vn 0.6085 0.2868 -0.7400 +vn 0.7769 0.2723 -0.5677 +vn 0.2238 0.1445 -0.9639 +vn 0.4823 0.3914 -0.7837 +vn 0.4059 -0.0703 -0.9112 +vn 0.1984 0.0143 -0.9800 +vn -0.0156 0.0695 -0.9975 +vn 0.3273 0.0921 -0.9404 +vn 0.2286 0.0054 -0.9735 +vn 0.6102 0.7222 -0.3257 +vn 0.6443 0.5803 -0.4981 +vn 0.4969 0.1416 -0.8562 +vn 0.4749 -0.0910 -0.8753 +vn 0.6870 0.1214 -0.7165 +vn 0.8579 -0.2672 -0.4390 +vn 0.7796 -0.1825 -0.5992 +vn 0.1208 0.3971 -0.9098 +vn 0.1075 0.5451 -0.8314 +vn 0.0761 0.5486 -0.8326 +vn 0.3651 0.7087 -0.6037 +vn 0.8210 -0.3904 -0.4167 +vn 0.8331 -0.3228 -0.4492 +vn 0.5980 -0.4679 -0.6507 +vn 0.2695 0.5104 -0.8166 +vn 0.6652 -0.1336 -0.7347 +vn 0.7261 -0.0753 -0.6835 +vn 0.5408 -0.1514 -0.8274 +vn 0.6207 0.4346 -0.6526 +vn 0.3602 0.6969 -0.6202 +vn 0.2923 0.8174 -0.4963 +vn 0.6549 0.4616 -0.5984 +vn 0.7013 -0.1214 -0.7024 +vn 0.3127 0.0149 -0.9498 +vn 0.3730 -0.2646 -0.8893 +vn 0.2068 0.9225 -0.3261 +vn 0.4428 0.8057 -0.3933 +vn 0.6128 0.6523 -0.4461 +vn -0.0282 -0.5216 -0.8527 +vn 0.2269 -0.4823 -0.8461 +vn -0.0625 -0.2963 -0.9530 +vn 0.9255 -0.2612 -0.2742 +vn 0.8782 -0.3583 -0.3167 +vn 0.7431 0.5356 -0.4013 +vn 0.7497 0.5979 -0.2835 +vn 0.8369 -0.2377 -0.4930 +vn 0.1306 0.5947 -0.7933 +vn 0.2395 0.5098 -0.8263 +vn 0.4942 0.2256 -0.8396 +vn 0.4387 0.0211 -0.8984 +vn 0.7810 0.0588 -0.6218 +vn 0.7757 -0.3764 -0.5066 +vn 0.2367 -0.1436 -0.9609 +vn 0.5078 0.1003 -0.8556 +vn 0.1036 -0.1009 -0.9895 +vn 0.4829 0.2882 -0.8269 +vn 0.4273 0.5748 -0.6979 +vn 0.3231 0.6484 -0.6894 +vn 0.7422 -0.0986 -0.6628 +vn 0.5223 -0.0708 -0.8498 +vn 0.3597 0.3844 -0.8502 +vn 0.5795 0.8063 -0.1185 +vn 0.4603 0.8254 -0.3268 +vn 0.3691 0.8831 -0.2895 +vn 0.6861 0.3121 -0.6571 +vn 0.6473 0.4401 -0.6223 +vn 0.8993 0.1483 -0.4114 +vn 0.2468 0.0393 -0.9683 +vn 0.4702 -0.7357 -0.4875 +vn 0.4528 -0.6808 -0.5758 +vn 0.8966 -0.0343 -0.4415 +vn 0.8987 0.0843 -0.4303 +vn 0.8959 0.0466 -0.4419 +vn 0.9774 0.1340 -0.1635 +vn 0.9007 0.1575 -0.4050 +vn 0.3724 0.5882 -0.7179 +vn 0.6001 -0.5021 -0.6227 +vn 0.4579 0.3117 -0.8325 +vn -0.1567 -0.3306 -0.9307 +vn -0.0155 -0.0506 -0.9986 +vn 0.3119 0.0191 -0.9499 +vn 0.3392 0.2827 -0.8972 +vn 0.3362 0.4579 -0.8230 +vn 0.5374 0.7997 -0.2676 +vn -0.1332 0.2907 -0.9475 +vn 0.7012 0.1840 -0.6888 +vn 0.1714 0.5455 -0.8204 +vn 0.5580 0.3128 -0.7686 +vn 0.5971 0.3016 -0.7433 +vn 0.9675 0.2147 -0.1340 +vn 0.2314 0.7831 -0.5773 +vn 0.7580 0.5782 -0.3018 +vn 0.2670 0.8375 -0.4768 +vn 0.2693 0.8599 -0.4336 +vn 0.5067 0.3950 -0.7663 +vn 0.7394 0.5132 -0.4357 +vn 0.3673 -0.2156 -0.9047 +vn 0.6777 -0.3981 -0.6182 +vn 0.6185 0.0661 -0.7830 +vn 0.4711 -0.5517 -0.6882 +vn 0.2506 0.5734 -0.7800 +vn 0.2726 0.0404 -0.9613 +vn 0.3665 -0.3395 -0.8662 +vn 0.9744 0.2145 -0.0671 +vn 0.9857 0.1509 -0.0744 +vn 0.2074 -0.2071 -0.9561 +vn -0.0326 -0.1888 -0.9815 +vn 0.4509 -0.5767 -0.6812 +vn 0.3959 -0.2961 -0.8693 +vn 0.8077 0.5514 -0.2088 +vn 0.9332 0.3326 -0.1365 +vn 0.8820 0.4566 -0.1162 +vn 0.8617 0.1065 -0.4962 +vn 0.1504 0.9084 -0.3900 +vn 0.4885 0.3529 -0.7980 +vn 0.3556 0.7052 -0.6134 +vn 0.1387 0.7361 -0.6625 +vn 0.3951 0.5494 -0.7363 +vn 0.3690 -0.0160 -0.9293 +vn 0.5278 -0.1434 -0.8372 +vn 0.3953 -0.1320 -0.9090 +vn 0.9794 0.0344 -0.1991 +vn -0.0106 -0.1659 -0.9861 +vn 0.1745 0.7218 -0.6697 +vn 0.1633 0.9568 -0.2405 +vn 0.4306 0.2942 -0.8532 +vn 0.5371 -0.1872 -0.8225 +vn 0.3508 0.3438 -0.8710 +vn 0.8106 -0.3958 -0.4315 +vn 0.9431 -0.0884 -0.3207 +vn 0.7107 0.6303 -0.3125 +vn 0.4906 0.3956 -0.7764 +vn 0.6379 0.5420 -0.5471 +vn 0.2648 -0.1351 -0.9548 +vn 0.5070 0.8298 -0.2331 +vn 0.5564 -0.1294 -0.8208 +vn 0.2610 0.8806 -0.3955 +vn 0.9583 0.2570 -0.1252 +vn 0.9614 0.2663 -0.0692 +vn 0.3949 0.8811 -0.2603 +vn 0.9102 0.2754 -0.3092 +vn 0.8881 0.3375 -0.3120 +vn 0.1150 0.8695 -0.4803 +vn 0.3658 0.4631 -0.8073 +vn 0.5063 -0.1983 -0.8392 +vn 0.5772 0.5500 -0.6036 +vn 0.9361 0.3433 -0.0766 +vn 0.5392 -0.2542 -0.8029 +vn -0.7761 -0.1922 -0.6006 +vn -0.0115 0.3481 -0.9374 +vn 0.9827 0.0780 -0.1680 +vn 0.2198 -0.1358 -0.9660 +vn 0.1342 0.8481 -0.5125 +vn 0.4880 -0.2447 -0.8379 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 1.0000 + +f 1/1/1 2/2/2 3/3/3 +f 4/4/4 5/5/5 6/6/6 +f 7/7/7 8/8/8 9/9/9 +f 10/10/10 6/6/6 11/11/11 +f 12/12/12 13/13/13 14/14/14 +f 7/7/7 13/13/13 12/12/12 +f 15/15/15 16/16/16 17/17/17 +f 18/18/18 19/19/19 20/20/20 +f 21/21/21 22/22/22 23/23/23 +f 24/24/24 11/11/11 25/25/25 +f 26/26/26 27/27/27 28/28/28 +f 29/29/29 30/30/30 31/31/31 +f 32/32/32 33/33/33 34/34/34 +f 35/35/35 25/25/25 36/36/36 +f 37/37/37 38/38/38 39/39/39 +f 25/25/25 40/40/40 41/41/41 +f 42/42/42 43/43/43 21/21/21 +f 44/44/44 45/45/45 46/46/46 +f 47/47/47 48/48/48 49/49/49 +f 50/50/50 51/51/51 52/52/52 +f 53/53/53 54/54/54 55/55/55 +f 56/56/56 57/57/57 58/58/58 +f 59/59/59 33/33/33 32/32/32 +f 60/60/60 46/46/46 61/61/61 +f 62/62/62 63/63/63 64/64/64 +f 65/65/65 66/66/66 67/67/67 +f 68/68/68 69/69/69 70/70/70 +f 71/71/71 72/72/72 73/73/73 +f 74/74/74 52/52/52 75/75/75 +f 76/76/76 22/22/22 77/77/77 +f 78/78/78 79/79/79 48/48/48 +f 75/75/75 59/59/59 80/80/80 +f 81/81/81 75/75/75 82/82/82 +f 83/83/83 84/84/84 49/49/49 +f 85/85/85 62/62/62 86/86/86 +f 20/20/20 19/19/19 87/87/87 +f 40/40/40 25/25/25 11/11/11 +f 88/88/88 89/89/89 90/90/90 +f 91/91/91 92/92/92 93/93/93 +f 94/94/94 95/95/95 96/96/96 +f 97/97/97 98/98/98 99/99/99 +f 100/100/100 67/67/67 15/15/15 +f 88/88/88 101/101/101 102/102/102 +f 103/103/103 104/104/104 105/105/105 +f 89/89/89 88/88/88 106/106/106 +f 64/64/64 107/107/107 108/108/108 +f 109/109/109 14/14/14 110/110/110 +f 111/111/111 112/112/112 113/113/113 +f 114/114/114 115/115/115 116/116/116 +f 117/117/117 118/118/118 31/31/31 +f 60/60/60 119/119/119 120/120/120 +f 14/14/14 109/109/109 121/121/121 +f 122/122/122 123/123/123 124/124/124 +f 69/69/69 68/68/68 125/125/125 +f 34/34/34 126/126/126 87/87/87 +f 17/17/17 16/16/16 28/28/28 +f 127/127/127 59/59/59 75/75/75 +f 42/42/42 128/128/128 9/9/9 +f 129/129/129 130/130/130 94/94/94 +f 131/131/131 124/124/124 123/123/123 +f 132/132/132 133/133/133 134/134/134 +f 135/135/135 136/136/136 137/137/137 +f 138/138/138 139/139/139 140/140/140 +f 135/135/135 124/124/124 131/131/131 +f 141/141/141 2/2/2 142/142/142 +f 143/143/143 103/103/103 144/144/144 +f 145/145/145 146/146/146 147/147/147 +f 97/97/97 125/125/125 68/68/68 +f 148/148/148 85/85/85 76/76/76 +f 115/115/115 149/149/149 150/150/150 +f 11/11/11 6/6/6 151/151/151 +f 79/79/79 78/78/78 152/152/152 +f 86/86/86 153/153/153 110/110/110 +f 154/154/154 45/45/45 44/44/44 +f 133/133/133 155/155/155 108/108/108 +f 93/93/93 92/92/92 57/57/57 +f 156/156/156 129/129/129 157/157/157 +f 53/53/53 91/91/91 158/158/158 +f 33/33/33 44/44/44 159/159/159 +f 157/157/157 160/160/160 135/135/135 +f 127/127/127 44/44/44 33/33/33 +f 139/139/139 50/50/50 74/74/74 +f 161/161/161 143/143/143 162/162/162 +f 163/163/163 164/164/164 10/10/10 +f 62/62/62 165/165/165 153/153/153 +f 166/166/166 64/64/64 167/167/167 +f 118/118/118 168/168/168 166/166/166 +f 163/163/163 24/24/24 35/35/35 +f 45/45/45 148/148/148 169/169/169 +f 38/38/38 35/35/35 170/170/170 +f 171/171/171 126/126/126 34/34/34 +f 126/126/126 172/172/172 173/173/173 +f 174/174/174 175/175/175 16/16/16 +f 176/176/176 177/177/177 101/101/101 +f 143/143/143 178/178/178 77/77/77 +f 140/140/140 74/74/74 81/81/81 +f 179/179/179 106/106/106 180/180/180 +f 181/181/181 81/81/81 182/182/182 +f 23/23/23 110/110/110 9/9/9 +f 131/131/131 174/174/174 15/15/15 +f 183/183/183 161/161/161 142/142/142 +f 184/184/184 185/185/185 83/83/83 +f 165/165/165 168/168/168 118/118/118 +f 186/186/186 187/187/187 185/185/185 +f 106/106/106 102/102/102 26/26/26 +f 110/110/110 14/14/14 13/13/13 +f 188/188/188 73/73/73 150/150/150 +f 189/189/189 181/181/181 190/190/190 +f 177/177/177 176/176/176 99/99/99 +f 189/189/189 191/191/191 140/140/140 +f 192/192/192 193/193/193 119/119/119 +f 194/194/194 195/195/195 193/193/193 +f 30/30/30 29/29/29 196/196/196 +f 38/38/38 37/37/37 197/197/197 +f 198/198/198 98/98/98 68/68/68 +f 127/127/127 52/52/52 51/51/51 +f 19/19/19 18/18/18 199/199/199 +f 197/197/197 200/200/200 164/164/164 +f 124/124/124 135/135/135 160/160/160 +f 71/71/71 201/201/201 202/202/202 +f 123/123/123 179/179/179 175/175/175 +f 43/43/43 104/104/104 103/103/103 +f 2/2/2 1/1/1 203/203/203 +f 180/180/180 28/28/28 16/16/16 +f 204/204/204 28/28/28 27/27/27 +f 29/29/29 166/166/166 205/205/205 +f 139/139/139 138/138/138 206/206/206 +f 165/165/165 117/117/117 109/109/109 +f 144/144/144 156/156/156 141/141/141 +f 103/103/103 143/143/143 22/22/22 +f 207/207/207 179/179/179 123/123/123 +f 147/147/147 146/146/146 208/208/208 +f 209/209/209 106/106/106 179/179/179 +f 98/98/98 198/198/198 210/210/210 +f 211/211/211 212/212/212 213/213/213 +f 214/214/214 215/215/215 145/145/145 +f 136/136/136 66/66/66 3/3/3 +f 176/176/176 88/88/88 216/216/216 +f 94/94/94 130/130/130 213/213/213 +f 66/66/66 65/65/65 217/217/217 +f 126/126/126 171/171/171 120/120/120 +f 218/218/218 219/219/219 99/99/99 +f 148/148/148 41/41/41 40/40/40 +f 220/220/220 107/107/107 151/151/151 +f 208/208/208 146/146/146 221/221/221 +f 222/222/222 151/151/151 6/6/6 +f 10/10/10 164/164/164 223/223/223 +f 164/164/164 200/200/200 224/224/224 +f 131/131/131 67/67/67 66/66/66 +f 129/129/129 156/156/156 144/144/144 +f 23/23/23 22/22/22 76/76/76 +f 85/85/85 40/40/40 63/63/63 +f 117/117/117 225/225/225 121/121/121 +f 63/63/63 151/151/151 107/107/107 +f 214/214/214 30/30/30 113/113/113 +f 226/226/226 227/227/227 228/228/228 +f 229/229/229 132/132/132 221/221/221 +f 46/46/46 60/60/60 171/171/171 +f 230/230/230 58/58/58 226/226/226 +f 19/19/19 152/152/152 231/231/231 +f 146/146/146 145/145/145 215/215/215 +f 185/185/185 187/187/187 232/232/232 +f 83/83/83 185/185/185 190/190/190 +f 84/84/84 83/83/83 182/182/182 +f 47/47/47 84/84/84 82/82/82 +f 78/78/78 47/47/47 80/80/80 +f 161/161/161 183/183/183 233/233/233 +f 50/50/50 139/139/139 39/39/39 +f 51/51/51 50/50/50 170/170/170 +f 154/154/154 51/51/51 36/36/36 +f 45/45/45 154/154/154 41/41/41 +f 46/46/46 169/169/169 77/77/77 +f 2/2/2 141/141/141 137/137/137 +f 112/112/112 229/229/229 215/215/215 +f 143/143/143 161/161/161 234/234/234 +f 145/145/145 235/235/235 70/70/70 +f 78/78/78 32/32/32 231/231/231 +f 166/166/166 168/168/168 165/165/165 +f 236/236/236 194/194/194 192/192/192 +f 237/237/237 111/111/111 196/196/196 +f 134/134/134 108/108/108 107/107/107 +f 220/220/220 238/238/238 208/208/208 +f 239/239/239 237/237/237 205/205/205 +f 72/72/72 202/202/202 104/104/104 +f 211/211/211 130/130/130 129/129/129 +f 73/73/73 72/72/72 43/43/43 +f 150/150/150 73/73/73 42/42/42 +f 116/116/116 150/150/150 8/8/8 +f 227/227/227 116/116/116 7/7/7 +f 89/89/89 230/230/230 228/228/228 +f 209/209/209 56/56/56 230/230/230 +f 93/93/93 56/56/56 209/209/209 +f 158/158/158 93/93/93 207/207/207 +f 54/54/54 158/158/158 122/122/122 +f 55/55/55 54/54/54 240/240/240 +f 94/94/94 55/55/55 160/160/160 +f 132/132/132 112/112/112 133/133/133 +f 111/111/111 237/237/237 239/239/239 +f 155/155/155 239/239/239 167/167/167 +f 178/178/178 234/234/234 194/194/194 +f 133/133/133 112/112/112 111/111/111 +f 77/77/77 178/178/178 236/236/236 +f 227/227/227 241/241/241 90/90/90 +f 241/241/241 12/12/12 216/216/216 +f 12/12/12 242/242/242 218/218/218 +f 242/242/242 121/121/121 219/219/219 +f 31/31/31 30/30/30 214/214/214 +f 121/121/121 225/225/225 97/97/97 +f 225/225/225 31/31/31 125/125/125 +f 234/234/234 233/233/233 195/195/195 +f 141/141/141 156/156/156 243/243/243 +f 202/202/202 201/201/201 212/212/212 +f 104/104/104 202/202/202 211/211/211 +f 244/244/244 245/245/245 246/246/246 +f 4/4/4 247/247/247 248/248/248 +f 249/249/249 250/250/250 251/251/251 +f 247/247/247 252/252/252 253/253/253 +f 254/254/254 255/255/255 256/256/256 +f 249/249/249 257/257/257 254/254/254 +f 258/258/258 259/259/259 260/260/260 +f 18/18/18 261/261/261 262/262/262 +f 263/263/263 264/264/264 265/265/265 +f 252/252/252 266/266/266 267/267/267 +f 26/26/26 268/268/268 269/269/269 +f 270/270/270 271/271/271 272/272/272 +f 273/273/273 274/274/274 275/275/275 +f 266/266/266 276/276/276 277/277/277 +f 278/278/278 279/279/279 280/280/280 +f 267/267/267 277/277/277 281/281/281 +f 282/282/282 264/264/264 263/263/263 +f 283/283/283 284/284/284 285/285/285 +f 286/286/286 287/287/287 49/49/49 +f 288/288/288 289/289/289 290/290/290 +f 291/291/291 292/292/292 293/293/293 +f 294/294/294 295/295/295 296/296/296 +f 297/297/297 298/298/298 273/273/273 +f 299/299/299 300/300/300 301/301/301 +f 302/302/302 303/303/303 304/304/304 +f 305/305/305 306/306/306 307/307/307 +f 308/308/308 309/309/309 70/70/70 +f 310/310/310 311/311/311 312/312/312 +f 289/289/289 313/313/313 314/314/314 +f 315/315/315 316/316/316 317/317/317 +f 318/318/318 286/286/286 48/48/48 +f 314/314/314 319/319/319 298/298/298 +f 313/313/313 320/320/320 319/319/319 +f 321/321/321 322/322/322 49/49/49 +f 323/323/323 315/315/315 324/324/324 +f 262/262/262 325/325/325 326/326/326 +f 327/327/327 328/328/328 253/253/253 +f 329/329/329 330/330/330 331/331/331 +f 332/332/332 333/333/333 334/334/334 +f 335/335/335 293/293/293 292/292/292 +f 336/336/336 337/337/337 338/338/338 +f 306/306/306 259/259/259 258/258/258 +f 329/329/329 339/339/339 102/102/102 +f 340/340/340 341/341/341 342/342/342 +f 343/343/343 344/344/344 339/339/339 +f 304/304/304 345/345/345 346/346/346 +f 347/347/347 348/348/348 349/349/349 +f 350/350/350 351/351/351 352/352/352 +f 353/353/353 354/354/354 355/355/355 +f 356/356/356 357/357/357 272/272/272 +f 299/299/299 358/358/358 359/359/359 +f 256/256/256 255/255/255 360/360/360 +f 361/361/361 362/362/362 363/363/363 +f 364/364/364 365/365/365 366/366/366 +f 275/275/275 274/274/274 326/326/326 +f 260/260/260 367/367/367 269/269/269 +f 368/368/368 290/290/290 314/314/314 +f 282/282/282 369/369/369 251/251/251 +f 370/370/370 371/371/371 372/372/372 +f 373/373/373 374/374/374 375/375/375 +f 376/376/376 377/377/377 378/378/378 +f 379/379/379 380/380/380 381/381/381 +f 382/382/382 383/383/383 384/384/384 +f 379/379/379 385/385/385 373/373/373 +f 386/386/386 387/387/387 388/388/388 +f 389/389/389 387/387/387 341/341/341 +f 390/390/390 235/235/235 147/147/147 +f 336/336/336 391/391/391 308/308/308 +f 392/392/392 316/316/316 315/315/315 +f 393/393/393 355/355/355 394/394/394 +f 253/253/253 328/328/328 395/395/395 +f 79/79/79 199/199/199 396/396/396 +f 324/324/324 265/265/265 349/349/349 +f 397/397/397 368/368/368 283/283/283 +f 398/398/398 378/378/378 346/346/346 +f 334/334/334 294/294/294 399/399/399 +f 400/400/400 380/380/380 371/371/371 +f 291/291/291 401/401/401 333/333/333 +f 402/402/402 275/275/275 284/284/284 +f 371/371/371 380/380/380 379/379/379 +f 368/368/368 297/297/297 402/402/402 +f 403/403/403 384/384/384 289/289/289 +f 404/404/404 388/388/388 387/387/387 +f 405/405/405 252/252/252 247/247/247 +f 302/302/302 324/324/324 348/348/348 +f 406/406/406 407/407/407 345/345/345 +f 271/271/271 270/270/270 406/406/406 +f 405/405/405 408/408/408 266/266/266 +f 409/409/409 285/285/285 316/316/316 +f 408/408/408 280/280/280 276/276/276 +f 358/358/358 284/284/284 275/275/275 +f 410/410/410 326/326/326 325/325/325 +f 374/374/374 258/258/258 411/411/411 +f 412/412/412 329/329/329 101/101/101 +f 389/389/389 413/413/413 317/317/317 +f 384/384/384 414/414/414 313/313/313 +f 415/415/415 416/416/416 268/268/268 +f 414/414/414 417/417/417 320/320/320 +f 265/265/265 264/264/264 251/251/251 +f 373/373/373 307/307/307 258/258/258 +f 418/418/418 419/419/419 388/388/388 +f 184/184/184 322/322/322 321/321/321 +f 303/303/303 356/356/356 271/271/271 +f 186/186/186 184/184/184 420/420/420 +f 339/339/339 268/268/268 26/26/26 +f 349/349/349 251/251/251 250/250/250 +f 311/311/311 421/421/421 394/394/394 +f 422/422/422 423/423/423 417/417/417 +f 177/177/177 210/210/210 338/338/338 +f 422/422/422 414/414/414 384/384/384 +f 300/300/300 299/299/299 424/424/424 +f 425/425/425 300/300/300 426/426/426 +f 427/427/427 352/352/352 351/351/351 +f 408/408/408 405/405/405 428/428/428 +f 198/198/198 309/309/309 308/308/308 +f 368/368/368 397/397/397 429/429/429 +f 430/430/430 396/396/396 199/199/199 +f 428/428/428 405/405/405 431/431/431 +f 363/363/363 362/362/362 432/432/432 +f 310/310/310 433/433/433 434/434/434 +f 375/375/375 374/374/374 416/416/416 +f 435/435/435 263/263/263 340/340/340 +f 436/436/436 388/388/388 419/419/419 +f 268/268/268 416/416/416 411/411/411 +f 367/367/367 437/437/437 27/27/27 +f 270/270/270 351/351/351 407/407/407 +f 403/403/403 280/280/280 279/279/279 +f 303/303/303 348/348/348 347/347/347 +f 341/341/341 387/387/387 386/386/386 +f 340/340/340 263/263/263 413/413/413 +f 438/438/438 361/361/361 375/375/375 +f 147/147/147 238/238/238 439/439/439 +f 344/344/344 438/438/438 415/415/415 +f 391/391/391 338/338/338 210/210/210 +f 440/440/440 441/441/441 442/442/442 +f 365/365/365 364/364/364 390/390/390 +f 385/385/385 381/381/381 246/246/246 +f 412/412/412 443/443/443 330/330/330 +f 440/440/440 372/372/372 335/335/335 +f 444/444/444 246/246/246 245/245/245 +f 410/410/410 445/445/445 359/359/359 +f 443/443/443 412/412/412 338/338/338 +f 392/392/392 323/323/323 327/327/327 +f 220/220/220 222/222/222 395/395/395 +f 439/439/439 378/378/378 377/377/377 +f 222/222/222 5/5/5 248/248/248 +f 247/247/247 4/4/4 223/223/223 +f 431/431/431 223/223/223 224/224/224 +f 373/373/373 385/385/385 444/444/444 +f 370/370/370 342/342/342 341/341/341 +f 265/265/265 324/324/324 315/315/315 +f 323/323/323 302/302/302 328/328/328 +f 356/356/356 347/347/347 360/360/360 +f 328/328/328 304/304/304 446/446/446 +f 365/365/365 447/447/447 352/352/352 +f 354/354/354 353/353/353 448/448/448 +f 449/449/449 447/447/447 377/377/377 +f 285/285/285 284/284/284 358/358/358 +f 295/295/295 450/450/450 448/448/448 +f 430/430/430 326/326/326 274/274/274 +f 451/451/451 377/377/377 447/447/447 +f 420/420/420 417/417/417 423/423/423 +f 321/321/321 320/320/320 417/417/417 +f 287/287/287 319/319/319 320/320/320 +f 286/286/286 298/298/298 319/319/319 +f 318/318/318 273/273/273 298/298/298 +f 404/404/404 452/452/452 453/453/453 +f 288/288/288 276/276/276 280/280/280 +f 429/429/429 277/277/277 276/276/276 +f 397/397/397 281/281/281 277/277/277 +f 409/409/409 392/392/392 281/281/281 +f 285/285/285 301/301/301 317/317/317 +f 436/436/436 246/246/246 381/381/381 +f 454/454/454 352/352/352 447/447/447 +f 389/389/389 455/455/455 452/452/452 +f 390/390/390 364/364/364 70/70/70 +f 318/318/318 396/396/396 274/274/274 +f 406/406/406 304/304/304 303/303/303 +f 456/456/456 301/301/301 300/300/300 +f 457/457/457 407/407/407 351/351/351 +f 378/378/378 439/439/439 446/446/446 +f 220/220/220 446/446/446 439/439/439 +f 458/458/458 345/345/345 407/407/407 +f 433/433/433 435/435/435 459/459/459 +f 441/441/441 342/342/342 370/370/370 +f 312/312/312 282/282/282 435/435/435 +f 394/394/394 369/369/369 282/282/282 +f 355/355/355 249/249/249 369/369/369 +f 354/354/354 257/257/257 249/249/249 +f 343/343/343 331/331/331 450/450/450 +f 344/344/344 343/343/343 295/295/295 +f 334/334/334 438/438/438 344/344/344 +f 333/333/333 361/361/361 438/438/438 +f 401/401/401 362/362/362 361/361/361 +f 293/293/293 432/432/432 362/362/362 +f 372/372/372 371/371/371 432/432/432 +f 449/449/449 376/376/376 398/398/398 +f 457/457/457 350/350/350 460/460/460 +f 460/460/460 346/346/346 345/345/345 +f 455/455/455 456/456/456 425/425/425 +f 398/398/398 460/460/460 350/350/350 +f 317/317/317 301/301/301 456/456/456 +f 354/354/354 450/450/450 331/331/331 +f 257/257/257 331/331/331 330/330/330 +f 254/254/254 330/330/330 443/443/443 +f 255/255/255 443/443/443 337/337/337 +f 272/272/272 366/366/366 365/365/365 +f 360/360/360 337/337/337 336/336/336 +f 357/357/357 336/336/336 366/366/366 +f 452/452/452 425/425/425 461/461/461 +f 386/386/386 381/381/381 380/380/380 +f 434/434/434 441/441/441 462/462/462 +f 459/459/459 342/342/342 441/441/441 +f 226/226/226 228/228/228 230/230/230 +f 226/226/226 114/114/114 227/227/227 +f 213/213/213 95/95/95 94/94/94 +f 213/213/213 130/130/130 211/211/211 +f 296/296/296 399/399/399 294/294/294 +f 448/448/448 296/296/296 295/295/295 +f 448/448/448 450/450/450 354/354/354 +f 440/440/440 442/442/442 372/372/372 +f 440/440/440 462/462/462 441/441/441 +f 335/335/335 372/372/372 293/293/293 +f 239/239/239 155/155/155 111/111/111 +f 132/132/132 229/229/229 112/112/112 +f 217/217/217 1/1/1 3/3/3 +f 10/10/10 4/4/4 6/6/6 +f 13/13/13 7/7/7 9/9/9 +f 24/24/24 10/10/10 11/11/11 +f 242/242/242 12/12/12 14/14/14 +f 241/241/241 7/7/7 12/12/12 +f 463/463/463 15/15/15 17/17/17 +f 261/261/261 18/18/18 20/20/20 +f 128/128/128 21/21/21 23/23/23 +f 35/35/35 24/24/24 25/25/25 +f 180/180/180 26/26/26 28/28/28 +f 118/118/118 29/29/29 31/31/31 +f 231/231/231 32/32/32 34/34/34 +f 170/170/170 35/35/35 36/36/36 +f 206/206/206 37/37/37 39/39/39 +f 36/36/36 25/25/25 41/41/41 +f 128/128/128 42/42/42 21/21/21 +f 159/159/159 44/44/44 46/46/46 +f 84/84/84 47/47/47 49/49/49 +f 74/74/74 50/50/50 52/52/52 +f 96/96/96 53/53/53 55/55/55 +f 230/230/230 56/56/56 58/58/58 +f 80/80/80 59/59/59 32/32/32 +f 192/192/192 60/60/60 61/61/61 +f 165/165/165 62/62/62 64/64/64 +f 100/100/100 65/65/65 67/67/67 +f 309/309/309 68/68/68 70/70/70 +f 188/188/188 71/71/71 73/73/73 +f 81/81/81 74/74/74 75/75/75 +f 169/169/169 76/76/76 77/77/77 +f 47/47/47 78/78/78 48/48/48 +f 82/82/82 75/75/75 80/80/80 +f 182/182/182 81/81/81 82/82/82 +f 322/322/322 83/83/83 49/49/49 +f 76/76/76 85/85/85 86/86/86 +f 173/173/173 20/20/20 87/87/87 +f 63/63/63 40/40/40 11/11/11 +f 216/216/216 88/88/88 90/90/90 +f 158/158/158 91/91/91 93/93/93 +f 55/55/55 94/94/94 96/96/96 +f 219/219/219 97/97/97 99/99/99 +f 463/463/463 100/100/100 15/15/15 +f 106/106/106 88/88/88 102/102/102 +f 144/144/144 103/103/103 105/105/105 +f 209/209/209 89/89/89 106/106/106 +f 167/167/167 64/64/64 108/108/108 +f 153/153/153 109/109/109 110/110/110 +f 196/196/196 111/111/111 113/113/113 +f 227/227/227 114/114/114 116/116/116 +f 225/225/225 117/117/117 31/31/31 +f 171/171/171 60/60/60 120/120/120 +f 242/242/242 14/14/14 121/121/121 +f 240/240/240 122/122/122 124/124/124 +f 214/214/214 69/69/69 125/125/125 +f 231/231/231 34/34/34 87/87/87 +f 204/204/204 17/17/17 28/28/28 +f 52/52/52 127/127/127 75/75/75 +f 8/8/8 42/42/42 9/9/9 +f 157/157/157 129/129/129 94/94/94 +f 174/174/174 131/131/131 123/123/123 +f 221/221/221 132/132/132 134/134/134 +f 243/243/243 135/135/135 137/137/137 +f 191/191/191 138/138/138 140/140/140 +f 136/136/136 135/135/135 131/131/131 +f 162/162/162 141/141/141 142/142/142 +f 162/162/162 143/143/143 144/144/144 +f 235/235/235 145/145/145 147/147/147 +f 98/98/98 97/97/97 68/68/68 +f 169/169/169 148/148/148 76/76/76 +f 116/116/116 115/115/115 150/150/150 +f 63/63/63 11/11/11 151/151/151 +f 199/199/199 79/79/79 152/152/152 +f 23/23/23 86/86/86 110/110/110 +f 127/127/127 154/154/154 44/44/44 +f 134/134/134 133/133/133 108/108/108 +f 56/56/56 93/93/93 57/57/57 +f 243/243/243 156/156/156 157/157/157 +f 54/54/54 53/53/53 158/158/158 +f 34/34/34 33/33/33 159/159/159 +f 243/243/243 157/157/157 135/135/135 +f 59/59/59 127/127/127 33/33/33 +f 140/140/140 139/139/139 74/74/74 +f 142/142/142 161/161/161 162/162/162 +f 24/24/24 163/163/163 10/10/10 +f 86/86/86 62/62/62 153/153/153 +f 205/205/205 166/166/166 167/167/167 +f 29/29/29 118/118/118 166/166/166 +f 38/38/38 163/163/163 35/35/35 +f 46/46/46 45/45/45 169/169/169 +f 39/39/39 38/38/38 170/170/170 +f 159/159/159 171/171/171 34/34/34 +f 87/87/87 126/126/126 173/173/173 +f 15/15/15 174/174/174 16/16/16 +f 88/88/88 176/176/176 101/101/101 +f 22/22/22 143/143/143 77/77/77 +f 181/181/181 140/140/140 81/81/81 +f 175/175/175 179/179/179 180/180/180 +f 190/190/190 181/181/181 182/182/182 +f 128/128/128 23/23/23 9/9/9 +f 67/67/67 131/131/131 15/15/15 +f 203/203/203 183/183/183 142/142/142 +f 322/322/322 184/184/184 83/83/83 +f 117/117/117 165/165/165 118/118/118 +f 184/184/184 186/186/186 185/185/185 +f 180/180/180 106/106/106 26/26/26 +f 9/9/9 110/110/110 13/13/13 +f 149/149/149 188/188/188 150/150/150 +f 232/232/232 189/189/189 190/190/190 +f 210/210/210 177/177/177 99/99/99 +f 181/181/181 189/189/189 140/140/140 +f 60/60/60 192/192/192 119/119/119 +f 192/192/192 194/194/194 193/193/193 +f 113/113/113 30/30/30 196/196/196 +f 163/163/163 38/38/38 197/197/197 +f 309/309/309 198/198/198 68/68/68 +f 154/154/154 127/127/127 51/51/51 +f 152/152/152 19/19/19 199/199/199 +f 163/163/163 197/197/197 164/164/164 +f 240/240/240 124/124/124 160/160/160 +f 72/72/72 71/71/71 202/202/202 +f 174/174/174 123/123/123 175/175/175 +f 21/21/21 43/43/43 103/103/103 +f 142/142/142 2/2/2 203/203/203 +f 175/175/175 180/180/180 16/16/16 +f 437/437/437 204/204/204 27/27/27 +f 196/196/196 29/29/29 205/205/205 +f 39/39/39 139/139/139 206/206/206 +f 153/153/153 165/165/165 109/109/109 +f 162/162/162 144/144/144 141/141/141 +f 21/21/21 103/103/103 22/22/22 +f 122/122/122 207/207/207 123/123/123 +f 238/238/238 147/147/147 208/208/208 +f 207/207/207 209/209/209 179/179/179 +f 99/99/99 98/98/98 210/210/210 +f 69/69/69 214/214/214 145/145/145 +f 137/137/137 136/136/136 3/3/3 +f 218/218/218 176/176/176 216/216/216 +f 3/3/3 66/66/66 217/217/217 +f 172/172/172 126/126/126 120/120/120 +f 176/176/176 218/218/218 99/99/99 +f 85/85/85 148/148/148 40/40/40 +f 222/222/222 220/220/220 151/151/151 +f 134/134/134 208/208/208 221/221/221 +f 5/5/5 222/222/222 6/6/6 +f 4/4/4 10/10/10 223/223/223 +f 223/223/223 164/164/164 224/224/224 +f 136/136/136 131/131/131 66/66/66 +f 105/105/105 129/129/129 144/144/144 +f 86/86/86 23/23/23 76/76/76 +f 62/62/62 85/85/85 63/63/63 +f 109/109/109 117/117/117 121/121/121 +f 64/64/64 63/63/63 107/107/107 +f 215/215/215 214/214/214 113/113/113 +f 215/215/215 229/229/229 221/221/221 +f 159/159/159 46/46/46 171/171/171 +f 87/87/87 19/19/19 231/231/231 +f 221/221/221 146/146/146 215/215/215 +f 190/190/190 185/185/185 232/232/232 +f 182/182/182 83/83/83 190/190/190 +f 82/82/82 84/84/84 182/182/182 +f 80/80/80 47/47/47 82/82/82 +f 32/32/32 78/78/78 80/80/80 +f 234/234/234 161/161/161 233/233/233 +f 170/170/170 50/50/50 39/39/39 +f 36/36/36 51/51/51 170/170/170 +f 41/41/41 154/154/154 36/36/36 +f 148/148/148 45/45/45 41/41/41 +f 61/61/61 46/46/46 77/77/77 +f 3/3/3 2/2/2 137/137/137 +f 113/113/113 112/112/112 215/215/215 +f 178/178/178 143/143/143 234/234/234 +f 69/69/69 145/145/145 70/70/70 +f 152/152/152 78/78/78 231/231/231 +f 64/64/64 166/166/166 165/165/165 +f 61/61/61 236/236/236 192/192/192 +f 205/205/205 237/237/237 196/196/196 +f 208/208/208 134/134/134 107/107/107 +f 107/107/107 220/220/220 208/208/208 +f 167/167/167 239/239/239 205/205/205 +f 43/43/43 72/72/72 104/104/104 +f 105/105/105 211/211/211 129/129/129 +f 42/42/42 73/73/73 43/43/43 +f 8/8/8 150/150/150 42/42/42 +f 7/7/7 116/116/116 8/8/8 +f 241/241/241 227/227/227 7/7/7 +f 90/90/90 89/89/89 228/228/228 +f 89/89/89 209/209/209 230/230/230 +f 207/207/207 93/93/93 209/209/209 +f 122/122/122 158/158/158 207/207/207 +f 240/240/240 54/54/54 122/122/122 +f 160/160/160 55/55/55 240/240/240 +f 157/157/157 94/94/94 160/160/160 +f 108/108/108 155/155/155 167/167/167 +f 236/236/236 178/178/178 194/194/194 +f 155/155/155 133/133/133 111/111/111 +f 61/61/61 77/77/77 236/236/236 +f 228/228/228 227/227/227 90/90/90 +f 90/90/90 241/241/241 216/216/216 +f 216/216/216 12/12/12 218/218/218 +f 218/218/218 242/242/242 219/219/219 +f 125/125/125 31/31/31 214/214/214 +f 219/219/219 121/121/121 97/97/97 +f 97/97/97 225/225/225 125/125/125 +f 194/194/194 234/234/234 195/195/195 +f 137/137/137 141/141/141 243/243/243 +f 211/211/211 202/202/202 212/212/212 +f 105/105/105 104/104/104 211/211/211 +f 436/436/436 244/244/244 246/246/246 +f 5/5/5 4/4/4 248/248/248 +f 369/369/369 249/249/249 251/251/251 +f 248/248/248 247/247/247 253/253/253 +f 250/250/250 254/254/254 256/256/256 +f 250/250/250 249/249/249 254/254/254 +f 411/411/411 258/258/258 260/260/260 +f 430/430/430 18/18/18 262/262/262 +f 413/413/413 263/263/263 265/265/265 +f 253/253/253 252/252/252 267/267/267 +f 27/27/27 26/26/26 269/269/269 +f 427/427/427 270/270/270 272/272/272 +f 402/402/402 273/273/273 275/275/275 +f 267/267/267 266/266/266 277/277/277 +f 408/408/408 278/278/278 280/280/280 +f 327/327/327 267/267/267 281/281/281 +f 435/435/435 282/282/282 263/263/263 +f 409/409/409 283/283/283 285/285/285 +f 48/48/48 286/286/286 49/49/49 +f 429/429/429 288/288/288 290/290/290 +f 401/401/401 291/291/291 293/293/293 +f 402/402/402 297/297/297 273/273/273 +f 285/285/285 299/299/299 301/301/301 +f 328/328/328 302/302/302 304/304/304 +f 444/444/444 305/305/305 307/307/307 +f 364/364/364 308/308/308 70/70/70 +f 433/433/433 310/310/310 312/312/312 +f 290/290/290 289/289/289 314/314/314 +f 413/413/413 315/315/315 317/317/317 +f 79/79/79 318/318/318 48/48/48 +f 297/297/297 314/314/314 298/298/298 +f 314/314/314 313/313/313 319/319/319 +f 287/287/287 321/321/321 49/49/49 +f 302/302/302 323/323/323 324/324/324 +f 430/430/430 262/262/262 326/326/326 +f 267/267/267 327/327/327 253/253/253 +f 343/343/343 329/329/329 331/331/331 +f 464/464/464 332/332/332 334/334/334 +f 391/391/391 336/336/336 338/338/338 +f 307/307/307 306/306/306 258/258/258 +f 101/101/101 329/329/329 102/102/102 +f 459/459/459 340/340/340 342/342/342 +f 329/329/329 343/343/343 339/339/339 +f 446/446/446 304/304/304 346/346/346 +f 256/256/256 347/347/347 349/349/349 +f 454/454/454 350/350/350 352/352/352 +f 393/393/393 353/353/353 355/355/355 +f 271/271/271 356/356/356 272/272/272 +f 424/424/424 299/299/299 359/359/359 +f 347/347/347 256/256/256 360/360/360 +f 375/375/375 361/361/361 363/363/363 +f 308/308/308 364/364/364 366/366/366 +f 410/410/410 275/275/275 326/326/326 +f 411/411/411 260/260/260 269/269/269 +f 297/297/297 368/368/368 314/314/314 +f 264/264/264 282/282/282 251/251/251 +f 442/442/442 370/370/370 372/372/372 +f 363/363/363 373/373/373 375/375/375 +f 398/398/398 376/376/376 378/378/378 +f 385/385/385 379/379/379 381/381/381 +f 403/403/403 382/382/382 384/384/384 +f 363/363/363 379/379/379 373/373/373 +f 436/436/436 386/386/386 388/388/388 +f 340/340/340 389/389/389 341/341/341 +f 451/451/451 390/390/390 147/147/147 +f 366/366/366 336/336/336 308/308/308 +f 323/323/323 392/392/392 315/315/315 +f 421/421/421 393/393/393 394/394/394 +f 248/248/248 253/253/253 395/395/395 +f 318/318/318 79/79/79 396/396/396 +f 348/348/348 324/324/324 349/349/349 +f 409/409/409 397/397/397 283/283/283 +f 460/460/460 398/398/398 346/346/346 +f 464/464/464 334/334/334 399/399/399 +f 370/370/370 400/400/400 371/371/371 +f 332/332/332 291/291/291 333/333/333 +f 283/283/283 402/402/402 284/284/284 +f 432/432/432 371/371/371 379/379/379 +f 283/283/283 368/368/368 402/402/402 +f 288/288/288 403/403/403 289/289/289 +f 389/389/389 404/404/404 387/387/387 +f 431/431/431 405/405/405 247/247/247 +f 303/303/303 302/302/302 348/348/348 +f 304/304/304 406/406/406 345/345/345 +f 465/465/465 271/271/271 406/406/406 +f 252/252/252 405/405/405 266/266/266 +f 392/392/392 409/409/409 316/316/316 +f 266/266/266 408/408/408 276/276/276 +f 410/410/410 358/358/358 275/275/275 +f 445/445/445 410/410/410 325/325/325 +f 416/416/416 374/374/374 411/411/411 +f 177/177/177 412/412/412 101/101/101 +f 455/455/455 389/389/389 317/317/317 +f 289/289/289 384/384/384 313/313/313 +f 339/339/339 415/415/415 268/268/268 +f 313/313/313 414/414/414 320/320/320 +f 349/349/349 265/265/265 251/251/251 +f 374/374/374 373/373/373 258/258/258 +f 404/404/404 418/418/418 388/388/388 +f 420/420/420 184/184/184 321/321/321 +f 465/465/465 303/303/303 271/271/271 +f 466/466/466 186/186/186 420/420/420 +f 102/102/102 339/339/339 26/26/26 +f 256/256/256 349/349/349 250/250/250 +f 312/312/312 311/311/311 394/394/394 +f 414/414/414 422/422/422 417/417/417 +f 412/412/412 177/177/177 338/338/338 +f 383/383/383 422/422/422 384/384/384 +f 426/426/426 300/300/300 424/424/424 +f 461/461/461 425/425/425 426/426/426 +f 270/270/270 427/427/427 351/351/351 +f 278/278/278 408/408/408 428/428/428 +f 391/391/391 198/198/198 308/308/308 +f 290/290/290 368/368/368 429/429/429 +f 18/18/18 430/430/430 199/199/199 +f 467/467/467 428/428/428 431/431/431 +f 379/379/379 363/363/363 432/432/432 +f 468/468/468 310/310/310 434/434/434 +f 415/415/415 375/375/375 416/416/416 +f 459/459/459 435/435/435 340/340/340 +f 244/244/244 436/436/436 419/419/419 +f 269/269/269 268/268/268 411/411/411 +f 269/269/269 367/367/367 27/27/27 +f 406/406/406 270/270/270 407/407/407 +f 382/382/382 403/403/403 279/279/279 +f 356/356/356 303/303/303 347/347/347 +f 400/400/400 341/341/341 386/386/386 +f 389/389/389 340/340/340 413/413/413 +f 415/415/415 438/438/438 375/375/375 +f 451/451/451 147/147/147 439/439/439 +f 339/339/339 344/344/344 415/415/415 +f 198/198/198 391/391/391 210/210/210 +f 447/447/447 365/365/365 390/390/390 +f 444/444/444 385/385/385 246/246/246 +f 329/329/329 412/412/412 330/330/330 +f 305/305/305 444/444/444 245/245/245 +f 358/358/358 410/410/410 359/359/359 +f 337/337/337 443/443/443 338/338/338 +f 281/281/281 392/392/392 327/327/327 +f 446/446/446 220/220/220 395/395/395 +f 451/451/451 439/439/439 377/377/377 +f 395/395/395 222/222/222 248/248/248 +f 431/431/431 247/247/247 223/223/223 +f 467/467/467 431/431/431 224/224/224 +f 307/307/307 373/373/373 444/444/444 +f 400/400/400 370/370/370 341/341/341 +f 413/413/413 265/265/265 315/315/315 +f 327/327/327 323/323/323 328/328/328 +f 357/357/357 356/356/356 360/360/360 +f 395/395/395 328/328/328 446/446/446 +f 427/427/427 365/365/365 352/352/352 +f 376/376/376 449/449/449 377/377/377 +f 299/299/299 285/285/285 358/358/358 +f 396/396/396 430/430/430 274/274/274 +f 390/390/390 451/451/451 447/447/447 +f 466/466/466 420/420/420 423/423/423 +f 420/420/420 321/321/321 417/417/417 +f 321/321/321 287/287/287 320/320/320 +f 287/287/287 286/286/286 319/319/319 +f 286/286/286 318/318/318 298/298/298 +f 418/418/418 404/404/404 453/453/453 +f 403/403/403 288/288/288 280/280/280 +f 288/288/288 429/429/429 276/276/276 +f 429/429/429 397/397/397 277/277/277 +f 397/397/397 409/409/409 281/281/281 +f 316/316/316 285/285/285 317/317/317 +f 386/386/386 436/436/436 381/381/381 +f 449/449/449 454/454/454 447/447/447 +f 404/404/404 389/389/389 452/452/452 +f 235/235/235 390/390/390 70/70/70 +f 273/273/273 318/318/318 274/274/274 +f 465/465/465 406/406/406 303/303/303 +f 425/425/425 456/456/456 300/300/300 +f 350/350/350 457/457/457 351/351/351 +f 346/346/346 378/378/378 446/446/446 +f 238/238/238 220/220/220 439/439/439 +f 457/457/457 458/458/458 407/407/407 +f 434/434/434 433/433/433 459/459/459 +f 442/442/442 441/441/441 370/370/370 +f 433/433/433 312/312/312 435/435/435 +f 312/312/312 394/394/394 282/282/282 +f 394/394/394 355/355/355 369/369/369 +f 355/355/355 354/354/354 249/249/249 +f 295/295/295 343/343/343 450/450/450 +f 294/294/294 344/344/344 295/295/295 +f 294/294/294 334/334/334 344/344/344 +f 334/334/334 333/333/333 438/438/438 +f 333/333/333 401/401/401 361/361/361 +f 401/401/401 293/293/293 362/362/362 +f 293/293/293 372/372/372 432/432/432 +f 454/454/454 449/449/449 398/398/398 +f 458/458/458 457/457/457 460/460/460 +f 458/458/458 460/460/460 345/345/345 +f 452/452/452 455/455/455 425/425/425 +f 454/454/454 398/398/398 350/350/350 +f 455/455/455 317/317/317 456/456/456 +f 257/257/257 354/354/354 331/331/331 +f 254/254/254 257/257/257 330/330/330 +f 255/255/255 254/254/254 443/443/443 +f 360/360/360 255/255/255 337/337/337 +f 427/427/427 272/272/272 365/365/365 +f 357/357/357 360/360/360 336/336/336 +f 272/272/272 357/357/357 366/366/366 +f 453/453/453 452/452/452 461/461/461 +f 400/400/400 386/386/386 380/380/380 +f 468/468/468 434/434/434 462/462/462 +f 434/434/434 459/459/459 441/441/441 +f 1/1/1 469/469/469 203/203/203 +f 469/469/469 470/470/470 203/203/203 +f 469/469/469 486/486/486 470/470/470 +f 486/486/486 487/487/487 470/470/470 +f 203/203/203 470/470/470 217/217/217 +f 470/470/470 471/471/471 217/217/217 +f 470/470/470 487/487/487 471/471/471 +f 487/487/487 488/488/488 471/471/471 +f 217/217/217 471/471/471 65/65/65 +f 471/471/471 472/472/472 65/65/65 +f 471/471/471 488/488/488 472/472/472 +f 488/488/488 489/489/489 472/472/472 +f 65/65/65 472/472/472 100/100/100 +f 472/472/472 473/473/473 100/100/100 +f 472/472/472 489/489/489 473/473/473 +f 489/489/489 490/490/490 473/473/473 +f 100/100/100 473/473/473 463/463/463 +f 473/473/473 474/474/474 463/463/463 +f 473/473/473 490/490/490 474/474/474 +f 490/490/490 491/491/491 474/474/474 +f 463/463/463 474/474/474 17/17/17 +f 474/474/474 475/475/475 17/17/17 +f 474/474/474 491/491/491 475/475/475 +f 491/491/491 492/492/492 475/475/475 +f 17/17/17 475/475/475 204/204/204 +f 475/475/475 476/476/476 204/204/204 +f 475/475/475 492/492/492 476/476/476 +f 492/492/492 493/493/493 476/476/476 +f 204/204/204 476/476/476 437/437/437 +f 476/476/476 477/477/477 437/437/437 +f 476/476/476 493/493/493 477/477/477 +f 493/493/493 494/494/494 477/477/477 +f 437/437/437 477/477/477 367/367/367 +f 477/477/477 478/478/478 367/367/367 +f 477/477/477 494/494/494 478/478/478 +f 494/494/494 495/495/495 478/478/478 +f 367/367/367 478/478/478 260/260/260 +f 478/478/478 479/479/479 260/260/260 +f 478/478/478 495/495/495 479/479/479 +f 495/495/495 496/496/496 479/479/479 +f 260/260/260 479/479/479 259/259/259 +f 479/479/479 480/480/480 259/259/259 +f 479/479/479 496/496/496 480/480/480 +f 496/496/496 497/497/497 480/480/480 +f 259/259/259 480/480/480 306/306/306 +f 480/480/480 481/481/481 306/306/306 +f 480/480/480 497/497/497 481/481/481 +f 497/497/497 498/498/498 481/481/481 +f 306/306/306 481/481/481 305/305/305 +f 481/481/481 482/482/482 305/305/305 +f 481/481/481 498/498/498 482/482/482 +f 498/498/498 499/499/499 482/482/482 +f 305/305/305 482/482/482 245/245/245 +f 482/482/482 483/483/483 245/245/245 +f 482/482/482 499/499/499 483/483/483 +f 499/499/499 500/500/500 483/483/483 +f 245/245/245 483/483/483 244/244/244 +f 483/483/483 484/484/484 244/244/244 +f 483/483/483 500/500/500 484/484/484 +f 500/500/500 501/501/501 484/484/484 +f 244/244/244 484/484/484 419/419/419 +f 484/484/484 485/485/485 419/419/419 +f 484/484/484 501/501/501 485/485/485 +f 501/501/501 502/502/502 485/485/485 diff --git a/hairline/models/face-parsing/config.json b/hairline/models/face-parsing/config.json new file mode 100644 index 0000000..ec0bfdc --- /dev/null +++ b/hairline/models/face-parsing/config.json @@ -0,0 +1,111 @@ +{ + "_name_or_path": "jonathandinu/face-parsing", + "architectures": [ + "SegformerForSemanticSegmentation" + ], + "attention_probs_dropout_prob": 0.0, + "classifier_dropout_prob": 0.1, + "decoder_hidden_size": 768, + "depths": [ + 3, + 6, + 40, + 3 + ], + "downsampling_rates": [ + 1, + 4, + 8, + 16 + ], + "drop_path_rate": 0.1, + "hidden_act": "gelu", + "hidden_dropout_prob": 0.0, + "hidden_sizes": [ + 64, + 128, + 320, + 512 + ], + "id2label": { + "0": "background", + "1": "skin", + "2": "nose", + "3": "eye_g", + "4": "l_eye", + "5": "r_eye", + "6": "l_brow", + "7": "r_brow", + "8": "l_ear", + "9": "r_ear", + "10": "mouth", + "11": "u_lip", + "12": "l_lip", + "13": "hair", + "14": "hat", + "15": "ear_r", + "16": "neck_l", + "17": "neck", + "18": "cloth" + }, + "image_size": 224, + "initializer_range": 0.02, + "label2id": { + "background": 0, + "skin": 1, + "nose": 2, + "eye_g": 3, + "l_eye": 4, + "r_eye": 5, + "l_brow": 6, + "r_brow": 7, + "l_ear": 8, + "r_ear": 9, + "mouth": 10, + "u_lip": 11, + "l_lip": 12, + "hair": 13, + "hat": 14, + "ear_r": 15, + "neck_l": 16, + "neck": 17, + "cloth": 18 + }, + "layer_norm_eps": 1e-06, + "mlp_ratios": [ + 4, + 4, + 4, + 4 + ], + "model_type": "segformer", + "num_attention_heads": [ + 1, + 2, + 5, + 8 + ], + "num_channels": 3, + "num_encoder_blocks": 4, + "patch_sizes": [ + 7, + 3, + 3, + 3 + ], + "reshape_last_stage": true, + "semantic_loss_ignore_index": 255, + "sr_ratios": [ + 8, + 4, + 2, + 1 + ], + "strides": [ + 4, + 2, + 2, + 2 + ], + "transformers_version": "4.37.0.dev0" +} diff --git a/hairline/models/face-parsing/preprocessor_config.json b/hairline/models/face-parsing/preprocessor_config.json new file mode 100644 index 0000000..89faa86 --- /dev/null +++ b/hairline/models/face-parsing/preprocessor_config.json @@ -0,0 +1,23 @@ +{ + "do_normalize": true, + "do_reduce_labels": false, + "do_rescale": true, + "do_resize": true, + "image_mean": [ + 0.485, + 0.456, + 0.406 + ], + "image_processor_type": "SegformerFeatureExtractor", + "image_std": [ + 0.229, + 0.224, + 0.225 + ], + "resample": 2, + "rescale_factor": 0.00392156862745098, + "size": { + "height": 512, + "width": 512 + } +} diff --git a/hairline/models/face_landmarker.task b/hairline/models/face_landmarker.task new file mode 100644 index 0000000..c50c845 Binary files /dev/null and b/hairline/models/face_landmarker.task differ diff --git a/hairline/obj_io.py b/hairline/obj_io.py new file mode 100644 index 0000000..11d12c2 --- /dev/null +++ b/hairline/obj_io.py @@ -0,0 +1,97 @@ +"""Minimal Wavefront OBJ reader/writer. + +Tailored to the project's face.obj: +- Latin-1 / GB-encoded comments allowed (we tolerate undecodable bytes). +- Vertices written with 4 decimal places (matches existing file). +- Preserves comment/mtllib/group lines if requested. +""" +from __future__ import annotations +from dataclasses import dataclass, field +from typing import Sequence + + +@dataclass +class ObjMesh: + """1-indexed in OBJ files; stored 0-indexed internally.""" + positions: list[tuple[float, float, float]] = field(default_factory=list) + texcoords: list[tuple[float, float]] = field(default_factory=list) + normals: list[tuple[float, float, float]] = field(default_factory=list) + # Each face is a list of 3 (pos_idx, uv_idx, normal_idx) tuples, 0-indexed. + # -1 means "absent". + faces: list[list[tuple[int, int, int]]] = field(default_factory=list) + header_lines: list[str] = field(default_factory=list) # comments / mtllib + + def n_v(self) -> int: return len(self.positions) + def n_vt(self) -> int: return len(self.texcoords) + def n_vn(self) -> int: return len(self.normals) + def n_f(self) -> int: return len(self.faces) + + +def read_obj(path: str) -> ObjMesh: + """Read an OBJ file, ignoring undecodable bytes in comments.""" + with open(path, "rb") as f: + raw = f.read() + text = raw.decode("latin-1", errors="replace") + mesh = ObjMesh() + + for line in text.splitlines(): + line = line.strip() + if not line: + continue + if line.startswith("#") or line.startswith("mtllib") or line.startswith("o ") or line.startswith("g ") or line.startswith("s "): + mesh.header_lines.append(line) + continue + parts = line.split() + kind = parts[0] + if kind == "v": + mesh.positions.append((float(parts[1]), float(parts[2]), float(parts[3]))) + elif kind == "vt": + mesh.texcoords.append((float(parts[1]), float(parts[2]))) + elif kind == "vn": + mesh.normals.append((float(parts[1]), float(parts[2]), float(parts[3]))) + elif kind == "f": + verts = [] + for spec in parts[1:]: + seg = spec.split("/") + pi = int(seg[0]) - 1 if seg[0] else -1 + ti = int(seg[1]) - 1 if len(seg) > 1 and seg[1] else -1 + ni = int(seg[2]) - 1 if len(seg) > 2 and seg[2] else -1 + verts.append((pi, ti, ni)) + # Triangulate fan if quad/n-gon (shouldn't happen for our mesh) + for k in range(1, len(verts) - 1): + mesh.faces.append([verts[0], verts[k], verts[k + 1]]) + # ignore everything else + return mesh + + +def write_obj(path: str, mesh: ObjMesh, header: Sequence[str] | None = None) -> None: + """Write an OBJ file with the project's conventions (1-indexed, 4dp).""" + out: list[str] = [] + if header is not None: + out.extend(header) + else: + out.append("# head3d extended face mesh") + out.append(f"# vertices={mesh.n_v()} texcoords={mesh.n_vt()} normals={mesh.n_vn()} faces={mesh.n_f()}") + + out.append("") + for x, y, z in mesh.positions: + out.append(f"v {x:.4f} {y:.4f} {z:.4f}") + out.append("") + for u, v in mesh.texcoords: + out.append(f"vt {u:.4f} {v:.4f} 0.0000") + out.append("") + for nx, ny, nz in mesh.normals: + out.append(f"vn {nx:.4f} {ny:.4f} {nz:.4f}") + out.append("") + for face in mesh.faces: + toks = [] + for pi, ti, ni in face: + a = str(pi + 1) + b = str(ti + 1) if ti >= 0 else "" + c = str(ni + 1) if ni >= 0 else "" + toks.append(f"{a}/{b}/{c}") + out.append("f " + " ".join(toks)) + + with open(path, "w", encoding="utf-8", newline="\r\n") as f: + f.write("\n".join(out)) + f.write("\n") diff --git a/hairline/reference/texture0.png b/hairline/reference/texture0.png new file mode 100644 index 0000000..8b47a7a Binary files /dev/null and b/hairline/reference/texture0.png differ diff --git a/hairline/reference/uv_template.png b/hairline/reference/uv_template.png new file mode 100644 index 0000000..39a6739 Binary files /dev/null and b/hairline/reference/uv_template.png differ