From 9f326c9f804c6656c6ec26e0e0f66de30a4aca04 Mon Sep 17 00:00:00 2001 From: ud18010 Date: Thu, 16 Jul 2026 11:45:22 +0800 Subject: [PATCH] =?UTF-8?q?ModelTranslator:=20=E5=87=8F=E9=9D=A2=20UV=20?= =?UTF-8?q?=E5=B1=95=E5=BC=80=E4=BC=98=E5=8C=96=E8=AE=BE=E8=AE=A1=EF=BC=88?= =?UTF-8?q?=E9=94=90=E8=BE=B9=20seam=20+=20MINIMUM=5FSTRETCH=20+=20?= =?UTF-8?q?=E8=B4=A8=E9=87=8F=E9=97=A8=E5=9B=9E=E9=80=80=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- ...26-07-16-decimate-uv-seam-unwrap-design.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-16-decimate-uv-seam-unwrap-design.md diff --git a/docs/superpowers/specs/2026-07-16-decimate-uv-seam-unwrap-design.md b/docs/superpowers/specs/2026-07-16-decimate-uv-seam-unwrap-design.md new file mode 100644 index 00000000..93c5eaaa --- /dev/null +++ b/docs/superpowers/specs/2026-07-16-decimate-uv-seam-unwrap-design.md @@ -0,0 +1,45 @@ +# 减面工具 UV 展开优化(锐边 seam + 常规展开)设计 + +日期:2026-07-16。前置:`2026-07-16-model-decimate-bake-design.md`(工具1 `model_decimate.py`)。 + +## 问题 + +`bl_decimate.py` 的 `_smart_unwrap` 用 Smart UV Project(angle_limit 66°)按面朝向分组投影;减面后的纯三角网格面法线抖动大,UV 被切成大量碎岛——烘焙接缝多、贴图空间浪费、mipmap 下接缝更明显。 + +## 方案(已定:方案A) + +锐边标 seam + 常规展开 + 质量检测回退: + +1. **标 seam**:EDIT 模式 `edges_select_sharp(sharpness=66°)` → `mark_seam`。接缝只落在硬边处,平滑区域保持为整岛 +2. **展开**:`uv.unwrap(method='MINIMUM_STRETCH')`(Blender 4.3+ SLIM,质量最好);该枚举不可用时回退 `ANGLE_BASED` +3. **打包**:`uv.pack_islands(rotate=True, margin=0.002)`(≈2048 图 4px,与原 smart_project 的 island_margin 一致) +4. **质量门**:封闭平滑曲面若无一条 seam 会展开重叠/翻转。展开后检测: + - 重叠:`bpy.ops.uv.select_overlap()` 后经 bmesh 统计选中面占比 + - 翻转:UV 面签名面积为负的占比(纯数学,不依赖 ops) + - 重叠占比 > 2% 或翻转占比 > 2% → 自动回退现有 smart_project 路径并打警告,保证不劣于现状 +5. **指标上报**:`MT_SUMMARY` 增加 `uv` 字段 `{mode, islands, fill, overlap, flipped}`——岛数(bmesh 提取"UV 连续边"邻接 + 纯逻辑 union-find)、UV 空间利用率(UV 面积和)、重叠/翻转占比。CLI 打印 + +## 接口变更 + +- `model_decimate.py` 新增 `--unwrap {seam,smart}`,默认 `seam`;`smart` 即原行为(也是质量门的回退路径) +- `bl_decimate.py` argv 追加第 4 参 `unwrap_mode` +- 其余接口/产物命名不变;`model_bake.py` 不受影响(只消费低模 UV) + +## 可单测纯逻辑(TDD) + +- `count_islands(n_faces, adjacent_pairs)`:union-find 数 UV 岛 +- `flipped_fraction(signed_areas)`:负面积占比 +- `fill_ratio(abs_areas)`:面积和(截断到 1.0) + +bmesh 提取邻接/面积的胶水代码走冒烟验证。 + +## 验证 + +- 单测:上述纯逻辑 +- 冒烟:`well1500.fbx --tris 5000` 分别跑 `--unwrap seam` 与 `--unwrap smart`,对比 islands/fill——要求 seam 模式岛数显著下降(数量级)、fill 不低于 smart、overlap/flipped ≈ 0;随后用新低模重跑一次烘焙确认贴图正常 +- Unity 手动验证由用户完成 + +## 局限 + +- seam 位置由几何硬边决定,全平滑无硬边模型会触发回退(此时 smart_project 本来就是合理选择) +- 不做手工 seam 编辑入口;要精细控制请在 DCC 里做好 UV 再直接喂 `model_bake.py`(工具2 不动 UV)