From 7499358def66152c4d0d394138ab8279bb410e2d Mon Sep 17 00:00:00 2001 From: ud18010 Date: Tue, 21 Jul 2026 12:35:00 +0800 Subject: [PATCH] =?UTF-8?q?ModelTranslator:=20=E5=87=8F=E9=9D=A2=E5=89=8D?= =?UTF-8?q?=20=5Fclean=5Fmesh=20=E7=84=8A=E6=8E=A5=E9=87=8D=E5=90=88?= =?UTF-8?q?=E7=82=B9+=E5=8E=BB=E9=80=80=E5=8C=96=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- Tools/ModelTranslator/bl_decimate.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/Tools/ModelTranslator/bl_decimate.py b/Tools/ModelTranslator/bl_decimate.py index aa310a72..a6722ca0 100644 --- a/Tools/ModelTranslator/bl_decimate.py +++ b/Tools/ModelTranslator/bl_decimate.py @@ -112,6 +112,30 @@ def _decimate(obj, ratio): _apply_modifier(obj, mod) +def _clean_mesh(obj, warnings): + """减面前清理:按局部包围盒对角线相对焊接重合点 + 去退化面,给 collapse 更干净的流形, + 减少被迫加的 seam。各步失败降级不中断。""" + import bpy + import mathutils + bb = [mathutils.Vector(c) for c in obj.bound_box] + diag = (bb[0] - bb[6]).length + bpy.context.view_layer.objects.active = obj + bpy.ops.object.mode_set(mode='EDIT') + bpy.ops.mesh.select_all(action='SELECT') + if diag > 0.0: + try: + bpy.ops.mesh.remove_doubles(threshold=diag * REL_WELD) + except RuntimeError as e: + warnings.append("remove_doubles 失败(%s),跳过焊接" % e) + else: + warnings.append("包围盒对角线为 0,跳过焊接") + try: + bpy.ops.mesh.dissolve_degenerate() + except RuntimeError as e: + warnings.append("dissolve_degenerate 失败(%s),跳过去退化" % e) + bpy.ops.object.mode_set(mode='OBJECT') + + SEAM_ANGLE_DEG = 66.0 # 锐边阈值:两面夹角超此值标 seam PACK_MARGIN = 0.002 # 岛间距 ≈ 2048 图 4px UVPM_EXT = "bl_ext.user_default.uvpackmaster4" # UVPackmaster 4 扩展模块名 @@ -119,6 +143,7 @@ UVPM_PIXEL_MARGIN = 4 # UVPM 岛间距(像素),与 PACK_MARGIN * UVPM_TE UVPM_TEX_SIZE = 2048 SEAM_ANGLE_SWEEP = (55.0, 45.0, 35.0) # 首选 SEAM_ANGLE_DEG 不过门时依次下探的 seam 角度 STRETCH_ITERS = 30 # minimize_stretch 松弛迭代次数 +REL_WELD = 1e-4 # 焊接距离占局部包围盒对角线比例(避免 cm/m 单位差异导致绝对阈值失准) def _clear_uv_layers(mesh): @@ -364,6 +389,7 @@ def main(): return obj = join_meshes(meshes) + _clean_mesh(obj, warnings) _triangulate(obj) orig = len(obj.data.polygons) cur = orig