From 7c3b86a995aa7a14a16dbb54c9ee9dfa52f53b29 Mon Sep 17 00:00:00 2001 From: ud18010 Date: Thu, 16 Jul 2026 10:44:33 +0800 Subject: [PATCH] =?UTF-8?q?ModelTranslator:=20=E7=83=98=E7=84=99=E5=B0=84?= =?UTF-8?q?=E7=BA=BF=E8=B7=9D=E7=A6=BB/=E5=91=BD=E5=90=8D/=E5=8C=85?= =?UTF-8?q?=E5=9B=B4=E7=9B=92=E6=A0=A1=E9=AA=8C=E7=BA=AF=E9=80=BB=E8=BE=91?= =?UTF-8?q?=EF=BC=88TDD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tools/ModelTranslator/bl_bake.py | 40 ++++++++++++++++++ Tools/ModelTranslator/tests/test_bl_bake.py | 47 +++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 Tools/ModelTranslator/bl_bake.py create mode 100644 Tools/ModelTranslator/tests/test_bl_bake.py diff --git a/Tools/ModelTranslator/bl_bake.py b/Tools/ModelTranslator/bl_bake.py new file mode 100644 index 00000000..88e1f50e --- /dev/null +++ b/Tools/ModelTranslator/bl_bake.py @@ -0,0 +1,40 @@ +"""Blender 内运行:高低模 Cycles 烘焙,低模 UV 上出 normal/ao/color/metallic/roughness。 +调用:blender -b --factory-startup --python bl_bake.py -- \ + +""" +import math +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) + +DEFAULT_RAY_PCT = 0.02 # 自动射线距离 = 低模包围盒对角线 * 2% +BBOX_TOL = 0.10 # 高低模包围盒尺寸相对差警告阈值 + +# (输出名, bake type, EMIT 来源的 Principled 输入, 目标图颜色空间) +BAKE_PASSES = [ + ("normal", 'NORMAL', None, 'Non-Color'), + ("ao", 'AO', None, 'Non-Color'), + ("color", 'EMIT', 'Base Color', 'sRGB'), + ("metallic", 'EMIT', 'Metallic', 'Non-Color'), + ("roughness", 'EMIT', 'Roughness', 'Non-Color'), +] + + +def estimate_ray_distance(bbox_dims, pct=DEFAULT_RAY_PCT): + """低模包围盒尺寸 (dx,dy,dz) -> 射线距离 = 对角线长 * pct。""" + return math.sqrt(sum(d * d for d in bbox_dims)) * pct + + +def output_stem(low_name): + """低模名去掉 _low 后缀作为输出前缀(对齐工具3纯网格贴图命名约定)。""" + return low_name[:-4] if low_name.endswith("_low") else low_name + + +def bbox_mismatch(high_dims, low_dims, tol=BBOX_TOL): + """任一轴尺寸相对差超 tol 返回 True;接近 0 的轴忽略(平面模型)。""" + for h, l in zip(high_dims, low_dims): + m = max(abs(h), abs(l)) + if m > 1e-9 and abs(h - l) / m > tol: + return True + return False diff --git a/Tools/ModelTranslator/tests/test_bl_bake.py b/Tools/ModelTranslator/tests/test_bl_bake.py new file mode 100644 index 00000000..7351b529 --- /dev/null +++ b/Tools/ModelTranslator/tests/test_bl_bake.py @@ -0,0 +1,47 @@ +import math +import os +import sys +import unittest + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +import bl_bake as bb + + +class TestEstimateRayDistance(unittest.TestCase): + def test_two_percent_of_bbox_diagonal(self): + # 3-4-12 直角箱对角线 = 13 + self.assertAlmostEqual(bb.estimate_ray_distance((3.0, 4.0, 12.0)), 0.26) + + def test_custom_pct(self): + self.assertAlmostEqual( + bb.estimate_ray_distance((1.0, 0.0, 0.0), pct=0.5), 0.5) + + +class TestOutputStem(unittest.TestCase): + def test_strips_low_suffix(self): + self.assertEqual(bb.output_stem("well1500_low"), "well1500") + + def test_keeps_name_without_suffix(self): + self.assertEqual(bb.output_stem("well1500"), "well1500") + + def test_only_strips_trailing_suffix(self): + self.assertEqual(bb.output_stem("low_poly_low"), "low_poly") + + +class TestBboxMismatch(unittest.TestCase): + def test_identical_ok(self): + self.assertFalse(bb.bbox_mismatch((1.0, 2.0, 3.0), (1.0, 2.0, 3.0))) + + def test_within_10_percent_ok(self): + self.assertFalse(bb.bbox_mismatch((1.0, 2.0, 3.0), (1.05, 1.9, 3.2))) + + def test_one_axis_exceeds(self): + self.assertTrue(bb.bbox_mismatch((1.0, 2.0, 3.0), (1.0, 2.0, 3.5))) + + def test_zero_axis_ignored(self): + # 平面模型某轴为 0,不应误报 + self.assertFalse(bb.bbox_mismatch((1.0, 0.0, 3.0), (1.0, 0.0, 3.0))) + + +if __name__ == "__main__": + unittest.main()