# 装配二维图公差/粗糙度查错流程规范

本文规范装配体二维图查错中，如何利用已经保存的三维接触功能语义，判断二维装配图中的尺寸公差、配合公差和粗糙度标注是否合理。

四类查错流程边界见：`../DIAGNOSTIC_FLOW_BOUNDARIES.md`。本文只规范二维装配图中的公差/粗糙度专项，不覆盖三维零件查错、三维装配体查错或二维零件图格式查错。

权威主流程如下：

1. 输入学生二维图路径，以及三维接触语义结果路径。
2. 后端抽取学生 DWG 中的尺寸、公差、粗糙度、形位公差、基准和几何图元。
3. 调用已有标准视图/线条归属流水线，完成候选视图、主视图和其他视图的生成、对齐、上色和归属提取，生成与学生图对应的标准视图证据。
4. 读取该流水线产物，获得上色二维图、各视图线条归属信息和线条两侧零件候选。
5. 对学生图中每条公差标注，识别其作用于哪两条二维线条或哪组几何边界。
6. 结合线条归属、线条位置和视图信息，判断该公差对应的是哪两个零件之间的哪一个二维分界/配合边界。
7. 用二维边界对应的零件对、名义尺寸、位置和视图信息，匹配三维接触语义中的 B-rep 接触面。
8. 汇总不同视图上的同一接口标注，避免把主视图、剖视图、侧视图中的同一配合割裂成多个独立问题。
9. 形成二维公差与三维接触功能的唯一或候选对应关系。
10. 如果二维公差存在但无法对应任何三维接触接口，判为“疑似多标/无效标注”候选。
11. 如果三维接触接口存在且按功能需要公差，但无法对应任何二维公差，判为“疑似漏标”候选。
12. 如果二维公差与三维接触接口唯一对应，再把二维标注、三维接触功能、连接方式和固定公差知识一起交给 AI 判定是否错标。

核心目标不是让 AI 直接“看图猜公差”，而是先把二维标注、二维线条、二维线条归属、视图来源、三维 B-rep 接触面、接触功能、连接方式和公差知识组织成闭合证据包，再交给 AI 判定。

公差知识相对固定，应优先作为内置提示词/规则说明进入 AI 判定提示，不依赖实时检索；只有后续知识库规模扩大或需要引用标准原文时，才引入检索。

## 1. 总原则

1. 公差判断必须以装配关系为核心。单个零件的几何形状不足以决定配合公差。
2. 三维信息必须区分两类语义：
   - 零件功能：零件在装配体中的整体作用。
   - 接触功能：某一对接触面/配合面承担的定位、支撑、传力、导向、密封、固定、运动等作用。
3. 接触不等于固定。判断公差时必须考虑连接方式：
   - 是否允许相对运动。
   - 是否承受径向/轴向/扭矩载荷。
   - 是否有螺钉、键、销、挡圈、肩部、胶接、焊接等其他正向固定。
   - 如果没有其他固定方式且要求固定，才需要考虑过盈/压入类配合。
4. 二维标注不能只按文字和直径判断，必须绑定到学生 DWG 图纸几何、标准视图线条归属和三维 B-rep 接触面。
5. 内部接触不参与当前二维装配图查错，除非后续显式打开内部接触分析范围。
6. 不同视图上的同一接口标注必须汇总，不能按视图割裂判断。
7. 几何证据只能给出候选和置信度，最终正确/错误必须结合固定公差知识和三维接触功能语义。

## 2. 输入资料

### 2.1 外部输入

用户启动二维装配图公差查错时，必须提供：

```text
student_dwg_path              学生二维装配图 DWG 路径
mechanical_context_dir        已保存的三维接触语义结果路径
ownership_context_dir         可选；如果为空，流程应重新生成二维线条归属
output_dir                    可选；查错输出目录
```

其中 `mechanical_context_dir` 不是普通三维模型路径，而是三维查错/接触分析阶段已经保存好的接触功能语义结果目录。它必须能提供每个外部接触接口的 B-rep face 级几何、接触功能描述和连接方式判断。

### 2.2 学生 DWG 提取结果

来源：由 `student_dwg_path` 通过 AutoCAD/DWG 抽取器生成。

关键文件：

- `dimensions.json`：全部尺寸标注。
- `dimensional-tolerances.json`：解析出的尺寸/配合公差。
- `geometry.json`：DWG 线、圆、圆弧等几何图元。
- `roughness.json`：粗糙度标注。
- `geometric-tolerances.json`：形位公差。
- `datums.json`：基准。

尺寸标注必须包含：

- `handle`：尺寸标注自身的 DWG 图元 ID。
- `text` / `raw_text`：标注文本。
- `nominal_size_mm` / `interface_diameter_mm`：名义尺寸。
- `fit_code`：如 `H7/js6`、`H6/f5`、`n6`。
- `xline1_point`、`xline2_point`：尺寸实际指向的两个定义点。
- `dim_line_point`：尺寸线位置点。

如果 `xline1_point/xline2_point` 缺失，不能做可靠的二维几何绑定，只能降级为 `text_position` 和 `bbox` 附近归属。

### 2.3 标准工程图视图和二维线条零件归属

来源：后端打开三维工程图/三维模型后，执行已有的标准视图生成、对齐、上色和线条归属流水线。

注意：这一块不是简单的“主视图放置/对齐”。它包含学生 DWG 主视图签名提取、SolidWorks 候选视图生成、候选 DWG 抽取、候选排序、图框中心对齐、主视图原点对齐、剖视图/其他视图区域分析与对齐、上色图生成、hover/grid 采样和所有视图线条归属汇总等细步骤。

权威细节见：

- `tools/drawing-diagnostics/README.md`
- `tools/drawing-diagnostics/SolidWorksViewCandidateGenerator/README.md`
- `tools/drawing-diagnostics/DRAWING_GEOMETRY_NORMALIZATION.md`

典型来源目录：

```text
runtime/current-standard-flow/41-all-view-ownership
```

当前优先使用：

```text
all-views-hover-grid-3mm-250ms-view-calibrated-complete.jsonl
```

用途：

- 判断尺寸文字/定义点附近属于哪个零件。
- 判断 DWG 线条两侧分别属于哪个零件。
- 为“二维线条是两个零件的分界线”提供证据。
- 标记线条属于哪个视图，支撑多视图汇总。

注意：二维归属是投影采样证据，不是最终 B-rep face 身份。

### 2.4 三维外部接触功能语义结果

来源：`mechanical_context_dir`。

示例目录：

```text
runtime/2/external_interface_recheck_v3_fast
```

必须包含：

- 外部接触面列表。
- `face_a/face_b`。
- `FaceKindA/FaceKindB`。
- 圆柱面的 `RadiusAmm/RadiusBmm`、axis、center、bbox。
- 平面接触的 center、bbox、overlap、gap。
- `component_function_profiles`。
- `interface_function_profiles`。
- `connection_assessment`。

三维接触结果必须保留 B-rep face 级证据：

```json
{
  "component_a": "...",
  "component_b": "...",
  "face_a": 31,
  "face_b": 567,
  "surface_kind": "cylinder",
  "diameter_mm": 70,
  "axis_a": [0, -1, 0],
  "axis_b": [0, 1, 0],
  "center_a_mm": [...],
  "center_b_mm": [...],
  "bbox_a_mm": [...],
  "bbox_b_mm": [...]
}
```

## 3. 证据收集流程

### 3.0 标准视图与归属证据生成

如果没有传入可用的 `ownership_context_dir`，后端必须先调用已有的标准视图/线条归属子流程生成证据。本文不重写该子流程的内部步骤，避免和现有实现脱节。

该子流程的产物必须至少能回答：

- 每条标准视图线条属于哪个视图。
- 每条线条两侧分别可能属于哪个零件。
- 一条线是否是两个零件之间的分界线。
- 学生 DWG 中的几何线条能否与标准视图线条建立位置对应。

这一步是二维公差绑定三维接触功能的前置条件，不能跳过。

### 3.1 解析二维公差标注

从 `dimensional-tolerances.json` 读取每条公差：

1. 解析名义尺寸。
2. 解析配合代号。
3. 标记完整性：
   - `hole_and_shaft_pair`
   - `single_designation`
   - `parse_warning`
4. 保留尺寸定义点：
   - `xline1_point`
   - `xline2_point`
   - `dim_line_point`

输出到上下文：

```json
"dwg_annotation": {
  "handle": "ADE",
  "text": "Φ60H7/f6",
  "interface_diameter_mm": 60,
  "fit_code": "H7/f6",
  "xline1_point": [...],
  "xline2_point": [...]
}
```

### 3.2 绑定二维 DWG 几何图元

用 `xline1_point/xline2_point` 到 `geometry.json` 中查找附近几何。

候选类型：

- `AcDbLine`
- `AcDbCircle`
- `AcDbArc`
- 必要时包括 spline/polyline 的规范化结果。

每个点输出：

```json
"drawing_geometry_binding": {
  "point_bindings": [
    {
      "reference_point_kind": "xline1_point",
      "nearest_geometry": [
        {
          "handle": "258",
          "object_name": "AcDbLine",
          "distance_mm": 0.0,
          "match_kind": "line_segment_distance"
        }
      ]
    }
  ]
}
```

DWG `handle` 是二维图纸图元 ID，不是三维 face id。

### 3.3 判断线条两侧零件归属

对每个候选 DWG 线/圆弧执行边界探测：

- 对直线：沿法向两侧偏移采样。
- 对圆/圆弧：沿径向内外偏移采样。

采样半径默认：

```text
probe_offset_mm = 3.0
ownership_search_radius_mm = 6.0
```

输出：

```json
"boundary_ownership": {
  "status": "boundary_pair_candidates_found",
  "sides": [
    {
      "side": "normal_positive",
      "owner_candidates": [...]
    },
    {
      "side": "normal_negative",
      "owner_candidates": [...]
    }
  ],
  "component_pair_candidates": [
    {
      "component_a": "...",
      "component_b": "...",
      "confidence": "medium"
    }
  ]
}
```

这一步的意义是识别“这条二维线是哪两个零件的分界线”。

### 3.4 匹配三维 B-rep 接触接口

用二维边界零件对匹配三维接口：

```text
drawing component pair == 3D interface component pair
```

同时检查名义尺寸：

```text
DWG nominal diameter == 3D B-rep interface diameter
```

匹配输出：

```json
"drawing_boundary_to_3d_interface_matches": [
  {
    "geometry_handle": "258",
    "reference_point_kind": "xline1_point",
    "drawing_component_a": "...",
    "drawing_component_b": "...",
    "interface_group_id": "cyl_interface_005",
    "diameter_mm": 60,
    "brep_binding_status": "brep_face_pair_candidate_by_boundary_pair_and_nominal_diameter",
    "brep_face_pairs": [
      {
        "face_a": 5,
        "face_b": 441,
        "center_a_mm": [...],
        "center_b_mm": [...],
        "axis_a": [...],
        "axis_b": [...]
      }
    ],
    "interface_function_descriptions": [...],
    "connection_assessment": {...}
  }
]
```

如果只匹配组件对，不匹配直径，必须标记为：

```text
boundary_component_pair_match_without_nominal_diameter_match
```

这种只能作为作者意图证据，不能作为公差正确性证据。

### 3.5 归并候选，形成最佳 B-rep 绑定

强匹配不能按“证据条数”直接等价为多个答案。

正确结构应为：

```json
"best_brep_interface_binding": {
  "interface_group_id": "cyl_interface_005",
  "diameter_mm": 60,
  "supporting_dwg_handles": ["258", "1D7", "261", "1D5", "1D9"],
  "supporting_xline_points": ["xline1_point", "xline2_point"],
  "brep_face_pairs": [...],
  "match_strength": "strong"
}
```

候选归并规则：

1. 先按 `interface_group_id` 去重。
2. 再按 `face_a/face_b` 去重。
3. 优先同时被 `xline1_point` 和 `xline2_point` 支持的接口。
4. 优先同时满足：
   - 直径匹配。
   - 二维边界零件对匹配。
   - 二维文字/定义点归属匹配。
5. 如果同组件对、同直径出现多个不同位置接口，必须增加 B-rep 投影位置匹配，不能只靠直径和组件对。

### 3.6 多视图汇总

二维装配图中，同一个三维接口可能在主视图、剖视图、侧视图或局部视图中出现。公差查错不能按单个视图割裂判断。

对每个候选绑定结果，必须保留：

- `view_id`：学生 DWG 标注所在视图。
- `standard_view_id`：对应的标准视图/上色视图。
- `dwg_annotation_handle`：学生图公差标注 handle。
- `dwg_geometry_handles`：该标注作用的二维线条/圆弧/圆 handle。
- `interface_group_id`：匹配到的三维接口。
- `face_a/face_b`：三维 B-rep 接触面编号。

汇总规则：

1. 先按 `interface_group_id` 汇总。
2. 没有稳定 `interface_group_id` 时，按 `component_a + component_b + face_a + face_b` 汇总。
3. 同一接口在多个视图中出现时，只能算作同一个三维接触接口的多视图证据。
4. 同一接口有多个公差标注时，要判断它们是重复表达、补充表达，还是互相冲突。
5. 一个二维公差如果同时匹配多个三维接口，不能直接判错，应进入 `needs_review`，除非位置投影能消除歧义。

### 3.7 多标、漏标和错标候选生成

证据绑定完成后，先生成候选，再交给 AI 判定。

#### 3.7.1 疑似多标

如果二维图中存在公差标注，但它无法对应到任何三维接触接口，则生成：

```text
over_annotated_or_unbound_tolerance
```

典型原因：

- 标注作用线条不是两个零件的配合/接触边界。
- 只找到了二维几何，但找不到线条两侧零件归属。
- 找到了零件对，但三维接触语义中没有对应外部接口。
- 名义尺寸、位置和组件对都无法支持三维接口绑定。

这类候选不能直接等价为错误，最终仍由 AI 结合图纸表达和上下文判断。

#### 3.7.2 疑似漏标

如果三维接触语义中存在外部接触接口，并且该接口功能通常需要明确公差，但所有视图汇总后仍找不到对应二维公差，则生成：

```text
missing_tolerance_for_3d_interface
```

漏标候选必须满足：

1. 接口属于当前二维装配图表达范围。
2. 接口不是内部接触或当前忽略范围。
3. 接口功能与连接方式说明其需要公差控制。
4. 多视图汇总后仍没有找到对应公差标注。

#### 3.7.3 疑似错标

如果二维公差与三维接口能够唯一对应，则生成：

```text
bound_tolerance_needs_ai_assessment
```

这类候选交给 AI 判断：

- 公差类型是否符合接口功能。
- 间隙/过渡/过盈方向是否合理。
- 是否与连接方式冲突。
- 是否与固定公差知识冲突。
- 是否存在表达不完整或重复冲突。

## 4. AI 判断证据包

发送给 AI 的证据包必须包含以下层次。

### 4.1 二维标注证据

- 标注文本。
- 标注 handle。
- 名义尺寸。
- 公差/配合代号。
- 是否完整表达孔轴配合。
- xline 定义点。
- 关联 DWG 几何 handle。

### 4.2 二维归属证据

- 标注位置归属。
- xline 点附近归属。
- DWG 线两侧归属。
- 归属置信度。

### 4.3 三维 B-rep 接触证据

- interface group id。
- component_a/component_b。
- face_a/face_b。
- surface kind。
- radius/diameter。
- axis/center/bbox。
- gap/confidence/verification。

### 4.4 功能语义证据

必须分开提供：

- 零件整体功能：`component_function_profiles`
- 接触局部功能：`interface_function_profiles`
- 连接方式评估：`connection_assessment`

### 4.5 固定公差知识

AI 不得凭几何直接猜具体公差值。公差知识相对固定，当前阶段作为内置提示词/规则说明传入 AI，不做实时检索。

固定知识至少应覆盖：

- 配合类别选择规则。
- 轴承/孔轴/定位/导向/过盈/间隙/过渡配合规则。
- 粗糙度推荐规则。
- 装配、拆卸、运动、传力场景下的公差选择原则。

AI 判定时必须同时引用：

1. 二维标注证据。
2. 二维线条归属和多视图汇总证据。
3. 三维 B-rep 接触接口。
4. 接触功能语义和连接方式。
5. 固定公差知识。

## 5. AI 判定规则

AI 输出只允许以下状态：

```text
correct
incorrect
missing
needs_review
```

### 5.1 correct

必须同时满足：

1. 二维标注绑定到明确的三维 B-rep 接触接口。
2. 接口功能、连接方式和固定公差知识支持该公差/粗糙度。
3. 二维表达完整且位置正确。

### 5.2 incorrect

必须有明确冲突证据，例如：

- 标注绑定到了错误接口。
- 公差类型与功能冲突。
- 应为间隙/过渡/过盈，标注明显相反。
- 配合代号与固定公差知识矛盾。

### 5.3 missing

必须谨慎使用。只有当：

- 三维接口功能明确要求公差/粗糙度。
- 该接口在二维图表达范围内。
- 未找到对应标注或全局标注不能覆盖。

才可判为 missing。

### 5.4 needs_review

以下情况必须保留为 needs_review：

- 同组件对、同直径有多个不同位置接口，缺少投影位置匹配。
- 连接方式不明确，无法判断是否需要过盈。
- 只有二维边界组件对匹配，但直径不匹配。
- 只有文字位置匹配，缺少 xline 定义点。
- 固定公差知识不能覆盖该特殊场景。

## 6. 粗糙度判断流程

粗糙度是面级要求，不是接口整体要求。

判断流程：

1. 读取 `roughness.json`。
2. 绑定粗糙度符号到 DWG 几何/面。
3. 通过二维归属和 B-rep 投影绑定到具体 face。
4. 查三维接触功能：
   - 定位面。
   - 滑动/转动面。
   - 轴承配合面。
   - 密封面。
   - 压入面。
   - 普通贴合/非关键面。
5. 根据固定粗糙度知识判断推荐 Ra/Rz 范围。
6. 判断：
   - 标注是否存在。
   - 标注是否过粗/过细。
   - 全局“其余”是否足够覆盖。

注意：同一个接触中的两个 face 可能需要不同粗糙度。

## 7. 推荐输出结构

每条公差候选最终应输出：

```json
{
  "candidate_id": "tolerance_ADE",
  "dwg_annotation": {...},
  "best_brep_interface_binding": {...},
  "candidate_brep_interface_bindings": [...],
  "component_function_context": [...],
  "interface_function_context": [...],
  "connection_assessment": {...},
  "fixed_tolerance_knowledge": [...],
  "ai_assessment": {
    "verdict": "needs_review",
    "reason": "...",
    "evidence_refs": [...]
  }
}
```

## 8. 当前已实现的桥接能力

当前流程已经具备：

- DWG 尺寸公差解析。
- `xline1_point/xline2_point` 提取。
- xline 点到 DWG 几何 handle 匹配。
- DWG 几何线两侧零件归属判断。
- 二维边界零件对到三维接口匹配。
- 三维接口携带 B-rep face pair、直径、center、axis、bbox、功能描述和连接方式。
- 区分“边界匹配但直径不匹配”的弱证据。

当前仍需继续完善：

- `best_brep_interface_binding` 的唯一化/排序输出。
- 同组件对、同直径、多位置接口的 B-rep 投影位置匹配。
- 粗糙度符号到具体 face 的绑定。
- AI 判定前的固定公差知识提示词注入。

## 9. 后端接口建议

建议二维装配图公差查错拆成两个阶段。

### 9.1 证据构建接口

证据构建接口负责完成从学生 DWG 到三维接触接口绑定的全部确定性流程：

```text
POST /api/drawing-assembly-diagnostics/build-interface-drawing-context
```

请求体建议包含：

```json
{
  "student_dwg_path": "D:/path/student.dwg",
  "mechanical_context_dir": "D:/CSharpProjects/agent4/runtime/2/external_interface_recheck_v3_fast",
  "ownership_context_dir": "",
  "output_dir": ""
}
```

职责边界：

- 抽取学生 DWG。
- 必要时打开三维工程图，放置/对齐主视图和其他视图。
- 生成上色二维图和线条归属。
- 识别学生图公差作用线条。
- 将二维线条、线条归属、视图位置和三维 B-rep 接触面绑定。
- 汇总多视图标注。
- 输出多标、漏标、错标候选。
- 不直接调用 AI 判定 correct/incorrect。

输出核心文件：

```text
interface_drawing_context.json
tolerance_assessment_context.json
roughness_assessment_context.json
unbound_tolerance_candidates.json
missing_tolerance_candidates.json
bound_tolerance_candidates.json
```

### 9.2 AI 判定接口

AI 判定应使用单独阶段：

```text
POST /api/drawing-assembly-diagnostics/assess-tolerances
POST /api/drawing-assembly-diagnostics/assess-roughness
```

当前已实现 `assess-tolerances`：默认输出确定性多标/漏标/绑定歧义候选；请求 `use_ai=true` 且已配置 AI key 时，再对已绑定候选做 AI 公差错标判断。AI 阶段只读取证据构建产物和固定公差知识提示词，不重新跑 AutoCAD/SolidWorks。

这样可以避免：

- 证据提取和 AI 判断耦合。
- 重复调用 AutoCAD/SolidWorks。
- 每次改 prompt 都重跑三维/二维提取。

证据构建产物应可缓存，AI 判定可重复运行。
