ModelTranslator: _unwrap_seam 加松弛+纹素均衡,seam 角度参数化

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ud18010
2026-07-21 11:19:06 +08:00
co-authored by Claude Opus 4.8
parent 788122b271
commit c23ab2508f
+18 -4
View File
@@ -116,6 +116,8 @@ PACK_MARGIN = 0.002 # 岛间距 ≈ 2048 图 4px
UVPM_EXT = "bl_ext.user_default.uvpackmaster4" # UVPackmaster 4 扩展模块名
UVPM_PIXEL_MARGIN = 4 # UVPM 岛间距(像素),与 PACK_MARGIN * UVPM_TEX_SIZE 同口径
UVPM_TEX_SIZE = 2048
SEAM_ANGLE_SWEEP = (55.0, 45.0, 35.0) # 首选 66° 不过门时依次下探的 seam 角度
STRETCH_ITERS = 30 # minimize_stretch 松弛迭代次数
def _clear_uv_layers(mesh):
@@ -135,18 +137,22 @@ def _unwrap_smart(obj):
bpy.ops.object.mode_set(mode='OBJECT')
def _unwrap_seam(obj, warnings):
"""锐边标 seam -> MINIMUM_STRETCH/ANGLE_BASED 展开 -> pack。碎岛远少于投影式。"""
def _unwrap_seam(obj, warnings, seam_angle_deg=SEAM_ANGLE_DEG):
"""锐边标 seam -> MINIMUM_STRETCH/ANGLE_BASED 展开 -> 松弛 -> 纹素均衡 -> pack。
seam_angle_deg 可变以支持角度扫描;重跑前清掉上一档残留 seam。"""
import bpy
import math
_clear_uv_layers(obj.data)
obj.data.uv_layers.new()
bpy.context.view_layer.objects.active = obj
bpy.ops.object.mode_set(mode='EDIT')
# 锐边标 seam:接缝只落在硬边处,平滑区域保持整岛
bpy.ops.mesh.select_mode(type='EDGE')
# 清掉上一档角度残留 seam(同一对象多角度扫描时必须)
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.mark_seam(clear=True)
# 锐边标 seam:接缝只落在硬边处,平滑区域保持整岛
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.mesh.edges_select_sharp(sharpness=math.radians(SEAM_ANGLE_DEG))
bpy.ops.mesh.edges_select_sharp(sharpness=math.radians(seam_angle_deg))
bpy.ops.mesh.mark_seam(clear=False)
bpy.ops.mesh.select_all(action='SELECT')
try:
@@ -154,6 +160,14 @@ def _unwrap_seam(obj, warnings):
except TypeError: # 老版本无 SLIM 枚举
warnings.append("MINIMUM_STRETCH 不可用,展开改用 ANGLE_BASED")
bpy.ops.uv.unwrap(method='ANGLE_BASED', margin=PACK_MARGIN)
try: # 角度松弛:压翻转/拉伸
bpy.ops.uv.minimize_stretch(iterations=STRETCH_ITERS)
except (RuntimeError, TypeError) as e:
warnings.append("minimize_stretch 不可用(%s),跳过松弛" % e)
try: # 统一纹素密度,避免大岛霸占分辨率
bpy.ops.uv.average_islands_scale()
except RuntimeError as e:
warnings.append("average_islands_scale 不可用(%s),跳过纹素均衡" % e)
try:
bpy.ops.uv.pack_islands(rotate=True, margin=PACK_MARGIN)
except RuntimeError: # headless 上下文不满足时靠 unwrap 自带打包