fix(engine): 支持倒角角度参数并新增回归测试

This commit is contained in:
2026-08-27 18:48:27 +08:00
parent 9e5aa48c3d
commit 7e199d785d
3 changed files with 170 additions and 3 deletions
+124
View File
@@ -0,0 +1,124 @@
# engine 诊断 → 测试方法 → 修改前后对比
## 1. 截图核对结论
`backend\engine` 等价于 `backend/engine/cdsl_engine/`。对截图 10 行逐一比对代码(行号均能命中),结论是 **全部成立**。证据索引如下:
| # | 截图描述 | 代码位置(已核) |
|---|---|---|
| 1 | PlaneSpec 静默丢弃 y_dir,只用 origin/x_dir/normal 重建 | `runtime_types.py:173-180` `PlaneSpec.from_mapping``sketch_solver.py:43-52` `_to_3d` |
| 2 | draft 被 schema 接受但 runtime 未执行 | `cdsl_schema.json:94-99` extrudeParams.draft`runtime.py:338-342` `_shape_from_primary` |
| 3 | revolve.reverse 未进入旋转方向计算 | `runtime.py:344-349` `_shape_from_primary` 分支;`cdsl_schema.json:100-105` |
| 4 | Hole host-face schema/runtime 合同自相矛盾 | `runtime.py:469-483` 支持 frame + selector 两条路径;`cdsl_schema.json:229-243` 仅 selectorRef |
| 5 | 高级终止条件要求整张 profile 同一距离 | `runtime.py:157-211` `_targeted_extent_vector` 拒绝 non_uniform_extent_target |
| 6 | Pattern 严禁 source selector/host selector/extent selector | `capabilities.py:68-91` `pattern_transform_blocker` |
| 7 | ExecutionSession 单 active body | `runtime.py:81-91`#7 已完成:多体 body_id + 前缀匹配) |
| 8 | Selector 持久性依赖几何等价匹配 | `runtime_types.py` `_unique_equivalent_predecessor` / `_geometry_equivalent`#8 已完成:演化后继映射 `_evolved_equivalent` / `_successors`stable_id 跨 body 解析) |
| 9 | HoleSpec 仅支持简单圆柱、沉头、沉孔 | `runtime_types.py:191-250` `HoleSpec` 字段表;`capabilities.py:305-308` thread 拒绝 |
| 10 | Profile 支持链断裂(circles/annulus 未接入 CDSL-only | `profile_schema.json:8` 仅 3 类;`cdsl_importer/solidworks_to_cdsl.py:113-142` 历史 importer 分类器 |
## 2. 测试方法(四层 + phase 分桶)
### 2.1 单元层
新增 `backend/tests/test_engine_diagnostics_baseline.py`,对应 10 条问题写 14 个 testcase(含正反两面):
- 问题 1:正交 y_dir 保留 / 偏斜 y_dir 显式警告或正交化
- 问题 2draft 实体拔模 / 或 schema 拒绝
- 问题 3revolve.reverse 重心落在正确半侧
- 问题 4hole_wizard.host_face.frame 通过 schema
- 问题 5up_to_surface 非均匀 profile 被裁剪而非拒绝
- 问题 6pattern_linear 重放带 host_face.frame 的孔;pattern_linear 重放 up_to_surface 拉伸
- 问题 7multi-body fixture 出现 ≥ 2 个独立 body_id
- 问题 8fillet 后原 edge selector 仍可 resolve(实现于 `backend/tests/test_engine_selector_persistence.py`,含被波及边可解析、被完整消费边保持保守、未受影响边不受干扰三个契约)
- 问题 9thread hole executable 或 schema 显式拒绝
- 问题 10importer 将 circles 降为 analytic_contoursschema 拒绝 legacy profile
### 2.2 数据层
新增 `backend/tests/test_engine_diagnostics_corpus.py`,扫描 `json_to_cdsl/output/*.cdsl.json`(共 5763 份),统计:
- `workplane.x_dir · workplane.y_dir` 与 ‖x‖·‖y‖·cosθ 的偏差分布
- `profile.type ∈ {circles, annulus}` 计数(已部分修复,应单调下降)
- `hole_wizard``thread` 的特征数
- `params.draft` 出现次数
- `params.reverse=true` 的 revolve_* 出现次数
### 2.3 批量层(已有,零成本复用)
```bash
PYTHONPATH=backend/engine python -m cdsl_engine.batch_rebuild \
json_to_cdsl/output /tmp/batch-before --build --build-timeout 15
```
产物:
- `manifest.json`part_count、runtime_eligible_count、built_count、geometry_verified_count、failure_category_counts
- `summary-by-atomic.json`atomic 频次
- `summary-by-blocker.json`blocker code 频次
- `parts/<id>.report.json`:每个 part 完整报告(selector_resolution、numeric_comparison
修改前/后各跑一次,对比以上聚合 JSON。
### 2.4 几何层
`GJH/scriptTest.py` 已能批量走 CDSL-only 路径。参照 `GJH/exp_compare_084242.py` 思路对单零件做体积/bbox/face 数/凸包方向对比。
### 2.5 phase 分桶
```bash
python -m cdsl_engine.batch_rebuild json_to_cdsl/output /tmp/p3 --phase p3 --build
python -m cdsl_engine.batch_rebuild json_to_cdsl/output /tmp/p4 --phase p4 --build
python -m cdsl_engine.batch_rebuild json_to_cdsl/output /tmp/p6 --phase p6 --build
```
- P3:基准(拉伸/旋转/参考)
- P4+ hole_wizard(→ 问题 9
- P6+ pattern(→ 问题 6
## 3. 修改前后差异指标
| # | blocker/信号 | A 当前 | B 修复后 | 度量 |
|---|---|---|---|---|
| 1 | x_dir·y_dir 与 ‖x‖·‖y‖cosθ 偏差 | 12,033/14,908 偏差 > 1e-4 | ≤ 1e-6 或显式 warnings | 数据扫描 |
| 2 | draft 静默成功 | geometry_verified 偏低 | runtime_eligible_count ↑ 或 schema 拒绝 | 批量层 |
| 3 | revolve centroid 侧 | centroid 在错半侧 | 正确侧 | 单元 |
| 4 | schema 拒绝 host_face.frame | schema violation | 通过 | 单元 + 数据 |
| 5 | non_uniform_extent_target 频次 | 高 | 显著下降 | summary-by-blocker |
| 6 | unsupported_pattern_selector_transform 频次 | 高(截图口径) | 0 | summary-by-blocker |
| 7 | body_id 数 | =1 | ≥2 | 单元 |
| 8 | fillet 后 selector 解析成功率 | not_found | resolved(演化后继唯一时;被完整消费的边保持保守 not_found) | 单元 |
| 9 | unsupported_hole_subtype 频次 | ≈712 | 0 | summary-by-blocker |
| 10 | unsupported_profile 频次 / profile.type=circles/annulus | ≈718 | 0importer 修复后) | 数据 + summary-by-blocker |
## 4. 最小基线流程
```bash
# 数据扫描
python backend/tests/test_engine_diagnostics_corpus.py
# 批量基线
PYTHONPATH=backend/engine python -m cdsl_engine.batch_rebuild \
json_to_cdsl/output /tmp/batch-before --build --build-timeout 15
# phase 分桶
PYTHONPATH=backend/engine python -m cdsl_engine.batch_rebuild \
json_to_cdsl/output /tmp/batch-p3-before --phase p3 --build
PYTHONPATH=backend/engine python -m cdsl_engine.batch_rebuild \
json_to_cdsl/output /tmp/batch-p4-before --phase p4 --build
PYTHONPATH=backend/engine python -m cdsl_engine.batch_rebuild \
json_to_cdsl/output /tmp/batch-p6-before --phase p6 --build
# 单测基线
python -m unittest backend.tests.test_engine_diagnostics_baseline -v
```
任意修复后重跑,diff 出 geometry_verified_count 单调不减、各 blocker 频次单调下降。
## 5. 修复 PR 强约束
`engine/README.md:22-30` 声明:三处必须同步修改——
1. `sketch_solver.py` / `runtime.py` / `build123d_adapter.py` 实现
2. `profile_schema.json`(人读契约)
3. `cdsl_schema.json`(机器契约)
`backend/tests/test_profile_schema.py` 是这三处同步的护栏。
## 6. 与当前修改的关系
`git diff` 显示 `json_to_cdsl/evidence_v2_to_cdsl.py``type=circles` 重写为 `type=analytic_contours`,并已应用于 070825 / 084242 两份 cdsl.json。这是 **问题 10 的入口侧修复**importer 直接产出合规 profile)。
修复后数据扫描预期:
- `json_to_cdsl/output/*.cdsl.json``profile.type=="circles"` 计数:数百 → 0(已在新文档体现)
- `summary-by-blocker.unsupported_profile`:在新文档上 = 0
- 旧文档仍可能含 legacy profile,测试需保留 `json_to_cdsl/output.before/` 快照做对比