diff --git a/Tools/ModelTranslator/bl_decimate.py b/Tools/ModelTranslator/bl_decimate.py index d0f0fc69..f56183bf 100644 --- a/Tools/ModelTranslator/bl_decimate.py +++ b/Tools/ModelTranslator/bl_decimate.py @@ -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 自带打包