Files
blender-vrm/editor/body_mesh
小煜 21222044c4 feat(body_mesh): Add edge UV data for facial and hair mesh components
- Add edge UV coordinate data for N00_000_00_FaceEyelash_00_FACE mesh instance with 112 edges
- Add edge UV coordinate data for N00_000_00_HairBack_00_HAIR mesh instance with 800 edges
- Update body_mesh module initialization and operations to support new mesh data
- Enhance panel UI and utility functions for mesh edge UV handling
- Add comprehensive UV matching test suite for validation
- Update registration module to include new mesh components
- Improve test utilities for edge UV data verification
2026-01-02 13:32:03 +08:00
..

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 结构

{
  "description": "区域描述",
  "total_edges": 边数量,
  "edge_uvs": [
    [[u1, v1], [u2, v2]],
    ...
  ]
}
  • description: 该文件的描述信息
  • total_edges: 存储的UV边数量
  • edge_uvs: UV边坐标数组每条边由两个UV坐标点组成

使用方法

保存当前选中的边到JSON

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加载并选中边

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视图中的边