ModelTranslator: 减面 ratio/容差纯逻辑(TDD)
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
"""Blender 内运行:FBX 减面到指定三角面数 + Smart UV 重展。
|
||||
调用:blender -b --factory-startup --python bl_decimate.py -- <src.fbx> <out.fbx> <target_tris>
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
TOLERANCE = 0.03 # 面数相对误差容忍
|
||||
MAX_RETRY = 2 # ratio 修正轮数上限
|
||||
|
||||
|
||||
def decimate_ratio(target, cur):
|
||||
"""Decimate collapse ratio;cur <= target 或非法时返回 1.0(不减面)。"""
|
||||
if cur <= 0 or cur <= target:
|
||||
return 1.0
|
||||
return target / float(cur)
|
||||
|
||||
|
||||
def within_tolerance(target, actual, tol=TOLERANCE):
|
||||
"""减面结果是否落在目标 ±tol 内。"""
|
||||
if target <= 0:
|
||||
return False
|
||||
return abs(actual - target) <= target * tol
|
||||
@@ -0,0 +1,40 @@
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
import bl_decimate as bd
|
||||
|
||||
|
||||
class TestDecimateRatio(unittest.TestCase):
|
||||
def test_normal_reduction(self):
|
||||
self.assertAlmostEqual(bd.decimate_ratio(5000, 1500000), 5000 / 1500000.0)
|
||||
|
||||
def test_current_below_target_returns_one(self):
|
||||
self.assertEqual(bd.decimate_ratio(5000, 3000), 1.0)
|
||||
|
||||
def test_current_equal_target_returns_one(self):
|
||||
self.assertEqual(bd.decimate_ratio(5000, 5000), 1.0)
|
||||
|
||||
def test_zero_current_returns_one(self):
|
||||
self.assertEqual(bd.decimate_ratio(5000, 0), 1.0)
|
||||
|
||||
|
||||
class TestWithinTolerance(unittest.TestCase):
|
||||
def test_exact_hit(self):
|
||||
self.assertTrue(bd.within_tolerance(5000, 5000))
|
||||
|
||||
def test_within_3_percent(self):
|
||||
self.assertTrue(bd.within_tolerance(5000, 5150)) # +3%
|
||||
self.assertTrue(bd.within_tolerance(5000, 4850)) # -3%
|
||||
|
||||
def test_outside_3_percent(self):
|
||||
self.assertFalse(bd.within_tolerance(5000, 5200))
|
||||
self.assertFalse(bd.within_tolerance(5000, 4700))
|
||||
|
||||
def test_zero_target_is_false(self):
|
||||
self.assertFalse(bd.within_tolerance(0, 0))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user