feat(cadfs): 补齐核心建模能力并建立代表性回归

- 新增 loft、双向切除、through-all/up-to-next 等 CADFS lowering 与 engine 支持
- 支持多种 reference plane、B-spline profile 和 circular pattern replay
- 保留 transform 历史,并烘焙安全的单源平移/旋转变换
- 改进 selector 绑定、拓扑快照和 pattern 变换处理
- 建立 17 个代表样本的转换、重建与比较回归工具链
- 补充 schema、author guidance、运行时和几何回归测试
This commit is contained in:
2026-09-07 18:21:07 +08:00
parent 4ad890b7b4
commit 038d38ed98
31 changed files with 2498 additions and 85 deletions
@@ -918,6 +918,25 @@ class EngineRuntimeFoundationTests(unittest.TestCase):
analysis = analyze_cdsl(cdsl)
self.assertIn("missing_parameter", [item.code for item in analysis.feature_results[0].blockers])
def test_two_sided_cut_uses_independent_forward_and_reverse_distances(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl
cdsl = self._base_block()
cdsl["geometry"]["sketches"].append({
"id": "cut", "workplane": {**_workplane(), "origin_mm": [0, 0, 5]},
"profile": {"type": "circle", "center": [0, 0], "radius_mm": 1},
})
cdsl["features"].append({
"id": "cut_1", "atomic_id": "extrude_cut_two_sided", "depends_on": ["base_add"],
"params": {
"distance_mm": 3, "reverse_distance_mm": 5,
"end_condition": {"type": "blind"}, "reverse_end_condition": {"type": "blind"},
}, "sketch_id": "cut",
})
with tempfile.TemporaryDirectory() as directory:
result = rebuild_cdsl(cdsl, Path(directory) / "two-sided-cut.step")
self.assertAlmostEqual(result["volume_mm3"], 1000.0 - 8.0 * 3.141592653589793, places=5)
def test_revolve_can_resolve_an_owner_qualified_reference_axis(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl
@@ -1038,6 +1057,22 @@ class EngineRuntimeFoundationTests(unittest.TestCase):
result = rebuild_cdsl(cdsl, root / f"{name}.step")
self.assertAlmostEqual(result["volume_mm3"], 1000 - expected_depth * 3.141592653589793, places=5)
def test_through_next_trims_a_partially_overlapping_profile_to_the_next_body_face(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl
base = self._base_block()
base["geometry"]["sketches"].append({
"id": "partial", "workplane": {"origin_mm": [0, 0, 12], "x_dir": [1, 0, 0], "normal": [0, 0, -1]},
"profile": {"type": "polygon", "vertices": [[3, -3], [9, -3], [9, 3], [3, 3]]},
})
base["features"].append({
"id": "partial_add", "atomic_id": "extrude_add_blind", "depends_on": ["base_add"],
"sketch_id": "partial", "params": {"distance_mm": 0, "end_condition": {"type": "through_next"}},
})
with tempfile.TemporaryDirectory() as directory:
result = rebuild_cdsl(base, Path(directory) / "partial-through-next.step")
self.assertAlmostEqual(result["volume_mm3"], 1000 + 24, places=5)
def test_up_to_body_extent_uses_a_uniquely_resolved_body_record(self) -> None:
from cdsl_engine.runtime import rebuild_cdsl