# Body Mesh UV Edge Selection JSON 文件说明

## 概述

这些JSON文件存储了VRM模型各材质区域需要融并(Dissolve)的边的UV坐标数据。通过UV坐标精确匹配，可以在3D视图中选中对应的边，即使UV存在重叠也不会误选。

## 文件列表

| 文件名 | 描述 |
|--------|------|
| `N00_000_00_Body_00_SKIN (Instance).json` | 身体皮肤区域 |
| `N00_000_00_Face_00_SKIN (Instance).json` | 脸部皮肤区域 |
| `N00_000_00_FaceMouth_00_FACE (Instance).json` | 口腔区域 |
| `N00_000_00_FaceEyeline_00_FACE (Instance).json` | 眼线区域 |
| `N00_000_00_hH_00_FACE (Instance).json` | 面部其他区域 |
| `N00_000_00_EyeIris_00_EYE (Instance).json` | 瞳孔/虹膜区域 |
| `N00_000_00_EyeWhite_00_EYE (Instance).json` | 眼白区域 |
| `N00_000_00_EyeHighlight_00_EYE (Instance).json` | 眼睛高光区域 |

## JSON 结构

```json
{
  "description": "区域描述",
  "total_edges": 边数量,
  "edge_uvs": [
    [[u1, v1], [u2, v2]],
    ...
  ]
}
```

- `description`: 该文件的描述信息
- `total_edges`: 存储的UV边数量
- `edge_uvs`: UV边坐标数组，每条边由两个UV坐标点组成

## 使用方法

### 保存当前选中的边到JSON

```python
import bpy, bmesh, json, os

obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
uv_layer = bm.loops.layers.uv.active

selected_uv_edges = []
seen = set()

for edge in bm.edges:
    if edge.select:
        for loop in edge.link_loops:
            uv1 = (round(loop[uv_layer].uv.x, 6), round(loop[uv_layer].uv.y, 6))
            uv2 = (round(loop.link_loop_next[uv_layer].uv.x, 6), round(loop.link_loop_next[uv_layer].uv.y, 6))
            key = (uv1, uv2) if uv1 < uv2 else (uv2, uv1)
            if key not in seen:
                seen.add(key)
                selected_uv_edges.append([list(uv1), list(uv2)])

data = {
    "description": "描述信息",
    "total_edges": len(selected_uv_edges),
    "edge_uvs": selected_uv_edges
}

with open("output.json", 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=2, ensure_ascii=False)
```

### 从JSON加载并选中边

```python
import bpy, bmesh, json

with open("input.json", 'r', encoding='utf-8') as f:
    data = json.load(f)

target_uvs = set()
for edge_uv in data['edge_uvs']:
    uv1 = (round(edge_uv[0][0], 6), round(edge_uv[0][1], 6))
    uv2 = (round(edge_uv[1][0], 6), round(edge_uv[1][1], 6))
    key = (uv1, uv2) if uv1 < uv2 else (uv2, uv1)
    target_uvs.add(key)

obj = bpy.context.active_object
bm = bmesh.from_edit_mesh(obj.data)
uv_layer = bm.loops.layers.uv.active

bpy.ops.mesh.select_all(action='DESELECT')
bm.select_mode = {'EDGE'}

for edge in bm.edges:
    for loop in edge.link_loops:
        uv1 = (round(loop[uv_layer].uv.x, 6), round(loop[uv_layer].uv.y, 6))
        uv2 = (round(loop.link_loop_next[uv_layer].uv.x, 6), round(loop.link_loop_next[uv_layer].uv.y, 6))
        key = (uv1, uv2) if uv1 < uv2 else (uv2, uv1)
        if key in target_uvs:
            edge.select = True
            break

bmesh.update_edit_mesh(obj.data)
```

## 注意事项

1. UV坐标精度为6位小数，匹配时使用相同精度
2. 即使不同材质区域的UV重叠，通过loop的UV数据独立存储特性，可以精确选中目标边
3. 这些文件用于在无法使用UV同步选区时，通过UV坐标反向选中3D视图中的边
