几何引擎新增open_slot功能。

This commit is contained in:
2026-09-07 16:44:06 +08:00
parent 9160c2bace
commit 9a3e09b9f5
6 changed files with 44 additions and 13 deletions
@@ -191,19 +191,27 @@ class PatternTransformContractTests(unittest.TestCase):
self.assertTrue(pattern.executable)
self.assertNotIn("unsupported_pattern_selector_transform", [blocker.code for blocker in pattern.blockers])
def test_mirror_source_stays_blocked(self) -> None:
"""回归护栏:mirror-as-source(plane selector)仍阻塞。
def test_mirror_source_is_replayed_by_linear_pattern(self) -> None:
"""mirror-as-source 放行 + 平移几何正确(体积 3000 精确)。
pattern_mirror 的镜像面是 reference_plane 引用;线性阵列重放镜像
特征需要把镜像面逐实例平移,当前执行器没有实例变换通道,放行会
产出"所有实例重合"的错误几何。因此 mirror 特征作为 pattern source
必须继续保持 unsupported_pattern_selector_transform。
早期(#6 修复前)mirror 的镜像面是 reference_plane 引用,无实例变换
通道,linear 阵列重放 mirror 会退化成"所有实例重合",因此曾阻塞
mirror-as-source。_translated_node 已把镜像面 frame 随实例平移内联、
源递归平移后重放(镜像副本 = reflect(源@t, 面@t))→ 该护栏已过时。
本测试把新语义固定下来:分析放行(无
unsupported_pattern_selector_transform)+ 几何正确。
baseline 10×10×10(x/y ∈ [-5,5]、z 0..10)。mirror 跨平面 y=5 镜像
base → box x ∈ [-5,5]、y ∈ [5,15](vol 1000,与 base 共面 fuse 为
2000)。linear 沿 +x 间距 12 重放 mirror 源 → 镜像面平移到 (12,5) 且
源 base 平移至 x ∈ [7,17],反射得 box x ∈ [7,17]、y ∈ [5,15]
(vol 1000)。期望总体积 = 1000 + 1000 + 1000 = 3000。
"""
base = _base_block()
base["features"].extend([
{
"id": "plane_ctx", "atomic_id": "reference_plane", "depends_on": [],
"params": {"plane": _workplane(origin=[0, 0, 0], normal=[0, 1, 0])},
"params": {"plane": _workplane(origin=[0, 5, 0], normal=[0, 1, 0])},
},
{
"id": "mirror", "atomic_id": "pattern_mirror", "depends_on": ["base_add", "plane_ctx"],
@@ -219,13 +227,16 @@ class PatternTransformContractTests(unittest.TestCase):
{
"id": "repeat", "atomic_id": "pattern_linear", "depends_on": ["mirror"],
"params": {"source_feature_ids": ["mirror"], "direction_1": [1, 0, 0],
"spacing_1_mm": 10, "pattern_count_1": 2},
"spacing_1_mm": 12, "pattern_count_1": 2},
},
])
analysis = analyze_cdsl(base)
pattern = next(item for item in analysis.feature_results if item.feature_id == "repeat")
self.assertFalse(pattern.executable)
self.assertIn("unsupported_pattern_selector_transform", [blocker.code for blocker in pattern.blockers])
self.assertTrue(pattern.executable)
self.assertNotIn("unsupported_pattern_selector_transform", [blocker.code for blocker in pattern.blockers])
with tempfile.TemporaryDirectory() as directory:
rebuilt = rebuild_cdsl(base, Path(directory) / "mirror-in-linear.step")
self.assertAlmostEqual(rebuilt["volume_mm3"], 3000.0, places=6)
def test_pattern_replays_face_selector_hole_geometry(self) -> None:
"""几何契约:无 frame 孔 pattern → 源孔 + 实例孔各切一个圆柱。