diff --git a/Tools/ModelTranslator/bl_decimate.py b/Tools/ModelTranslator/bl_decimate.py index 5ec82626..c5dacf1b 100644 --- a/Tools/ModelTranslator/bl_decimate.py +++ b/Tools/ModelTranslator/bl_decimate.py @@ -289,18 +289,30 @@ def _uvpm_repack(obj, warnings): def _do_unwrap(obj, mode, warnings): - """按模式展开(排布默认 UVPM4 增强,失败保底内置 pack); - seam 质量不达标自动回退 smart。返回 uv 指标 dict(含 mode)。""" + """按模式展开:seam 首选 66° 过门即用;否则扫 SEAM_ANGLE_SWEEP, + 取过门且岛数最少者(重跑恢复其 UV);全失败退 smart。排布 UVPM4 增强, + 只在最终 UV 上跑一次,失败保底内置 pack。返回 uv 指标 dict(含 mode)。""" if mode == "seam": - _unwrap_seam(obj, warnings) - uvpm = _uvpm_repack(obj, warnings) - m = _collect_uv_metrics(obj) - if uv_gate_ok(m["flipped"], m["overlap"]): - m["mode"] = uvpm_mode_label("seam", uvpm) + angles = [SEAM_ANGLE_DEG] + list(SEAM_ANGLE_SWEEP) + candidates = [] + for ang in angles: + _unwrap_seam(obj, warnings, seam_angle_deg=ang) + m = _collect_uv_metrics(obj) + m["angle"] = ang + candidates.append(m) + if uv_gate_ok(m["flipped"], m["overlap"]): + break # 该档已过门;更低角度只会更碎,无需再试 + best = pick_best_candidate(candidates) + if best is not None: + if best["angle"] != candidates[-1]["angle"]: + # 选中档不是最后跑的那档,重跑恢复其 UV(_unwrap_seam 会覆盖) + _unwrap_seam(obj, warnings, seam_angle_deg=best["angle"]) + uvpm = _uvpm_repack(obj, warnings) + m = _collect_uv_metrics(obj) + m["mode"] = uvpm_mode_label("seam@%d" % int(best["angle"]), uvpm) return m - warnings.append("seam 展开质量不达标(翻转 %.1f%% 重叠 %s),回退 smart_project" - % (m["flipped"] * 100, - "%.1f%%" % (m["overlap"] * 100) if m["overlap"] is not None else "未知")) + warnings.append("所有 seam 角度(%s)均未过质量门,回退 smart_project" + % "、".join("%d°" % int(a) for a in angles)) mode = "smart_fallback" _unwrap_smart(obj) uvpm = _uvpm_repack(obj, warnings)