tools/epro2/std: rewrite to Option 2 (objects dump) per downstream spec
Downstream came back with concrete requirements: don't pre-compute Std
shape[] tilde strings, just dump the raw EPRO2 `objects: {id: payload}`
dict and they'll write a ~100-LoC adapter on their side. Pulling the
tilde-mapping work back saves us from second-guessing positional fields
without their parser to verify against, and shortens our pcb_writer
from ~500 lines to ~40.
Output shape (Std envelope intact, just no `shape[]`):
{
"success": true, "code": 0,
"result": {
"uuid", "puuid", "title",
"docType": 3 | 1,
"components": {},
"dataStr": {
"head": {
"docType": "3" | "1",
"editorVersion": "facere-epro2/0.1 (epro2 <X.Y.Z>)",
"units": "mil",
"epro2_doc_uuid": ...,
"epro2_editor_version": ...,
},
"BBox": {x, y, width, height}, # mil
"layers": [...], # Std layer-string array
"objects": dict(doc.objects), # raw EPRO2, 1:1
"preference": {}, "netColors": [], "DRCRULE": {},
}
}
}
Per-doc spec downstream gave us:
- shape[] dropped (empty placeholder misleads adapter)
- all units mil (no mm conversion — Std canvas already declares mil)
- head.units="mil" so adapter doesn't have to guess
- BBox min/max across known x/y/startX/endX/centerX fields; adapter
can refine by walking path arrays itself
- layers[] keeps Std's 17-line default + inner SIGNAL layers actually
used (21~Inner1.., 22~Inner2..)
- empty stubs preference/netColors/DRCRULE for grep-based triage
New: docs/sources/epro2_to_std_mapping.md with the full EPRO2 OPTYPE →
Std verb table that downstream's adapter authors will copy from. Tables
include the layer-id remapping (the 5↔7 paste/mask flip, 11→10 outline,
12→11 multi, SIGNAL 15+→21+), PCB op mappings, SCH op mappings (marked
best-effort: no Std SCH samples in our corpus), and the 5-Voltage
placeholder COMPONENT → extra net flag trick. Extracted from the
previous Option-3 writer (commit fe6971f) so adapter writers don't
have to reverse-engineer it from source.
ESP-VoCat smoke: 6 PCB + 9 SCH = 15 JSON files, head.units=mil
preserved, no shape[] field present. 82 → 84 unit tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
64
log.md
64
log.md
@@ -4,6 +4,70 @@
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-29 04:30 std/ writer 翻 Option 2:raw objects dump + mapping doc
|
||||
|
||||
**Claude 会话**
|
||||
|
||||
接 `fe6971f`。下游同学回了具体规格:选 Option 2(objects dict 直接 dump),不要我们做 tilde 串映射,他自己写 ~100 LoC adapter 翻。把之前 Option 3(full Std `shape: ["TRACK~...", ...]`)那套删了,重写。
|
||||
|
||||
### 下游确认的规格
|
||||
|
||||
1. **`shape[]` 不要保留**——adapter 从 `objects` 重建,空占位反而误导
|
||||
2. **全 mil**——不转 mm,BBox 也 mil(Std `canvas` 那一行 `~mil~` 已经写了)
|
||||
3. **`head` 必带**:
|
||||
- `editorVersion` ← `facere-epro2/0.1 (epro2 <doc.head.editVersion>)`,Wokwi 据此选解析分支
|
||||
- `docType` ← `"3"` (PCB) / `"1"` (SCH)
|
||||
- `units` ← `"mil"`
|
||||
4. **`layers[]`** 沿用 Std 53-layer 字符串数组格式(`"1~TopLayer~#FF0000~..."`),inner SIGNAL 有用到才追加
|
||||
5. **保留空 stub** `preference / netColors / DRCRULE`——失败时 grep 路径稳定
|
||||
6. **per-doc 一个 .json**,平铺,不合并
|
||||
|
||||
### 写完三件
|
||||
|
||||
#### `tools/epro2/std/pcb_writer.py` 重写
|
||||
40 行核心逻辑(之前 Option 3 是 500 行):
|
||||
- `_gather_bbox_points`:扫所有 op 的 `x/y/startX/...` 等坐标字段,min/max
|
||||
- `_used_inner_signal_layers`:找真正有 primitive 的 SIGNAL 内层 id
|
||||
- envelope 直接 dump `dict(doc.objects)`
|
||||
|
||||
#### `tools/epro2/std/sch_writer.py` 重写
|
||||
更短——schematic 没 copper layer,layers=[]。其它结构跟 PCB 一样。
|
||||
|
||||
#### `docs/sources/epro2_to_std_mapping.md` 新增
|
||||
**这是给下游 adapter 的关键文档**——他写 100 LoC adapter 时按这个表查。内容:
|
||||
- EPRO2 layer id → Std layer id 重映射表(最坑:5↔7 mask/paste 反着、11→10 outline、12→11 multi、SIGNAL 15+→Std 21+)
|
||||
- PCB OPTYPE → Std verb 全表(TRACK / VIA / COPPERAREA / SOLIDREGION / CIRCLE / LIB+#@$PAD+TEXT)
|
||||
- SCH OPTYPE → Std verb 全表(W / N / T / LIB+#@$P)—— 标了 best-effort,没 Std SCH 实样
|
||||
- COMPONENT placement 旋转 + 平移公式(footprint-local → PCB-absolute)
|
||||
- 5-Voltage 占位符 `pid8a0e77bacb214e` 的 Global Net Name → 额外 N flag 的 trick
|
||||
|
||||
mapping doc 直接从 `fe6971f` 那个 Option 3 writer 提炼出来——他不用读我们代码,照表填就行。
|
||||
|
||||
### 实测
|
||||
|
||||
ESP-VoCat 6 PCB + 9 SCH = 15 JSON:
|
||||
- 一个典型 PCB: `objects=1719, layers=17, BBox=(-2293, -900, 2997×1899)`
|
||||
- `head.units = "mil"`、`head.editorVersion = "facere-epro2/0.1 (epro2 3.2.91)"`、`head.docType = "3"`
|
||||
- `shape` 字段已确认**不存在**
|
||||
- `objects` 原 payload 1:1 保留(含 LAYER ops 的 activeColor 等所有字段)
|
||||
|
||||
### 决策(Why)
|
||||
|
||||
- **不留空 `shape: []`**——下游说"误导 adapter"。明确不存在,比空数组更诚实
|
||||
- **`head.editorVersion` 加前缀 `facere-epro2/0.1`**——区分我们的输出 vs lceda 真实 Std;adapter 看到这个能猜出是 EPRO2 转过来的
|
||||
- **保留 `preference/netColors/DRCRULE` 空 stub**——下游说失败 grep 排查方便
|
||||
- **mapping doc 单独成文不混在 README**——adapter 作者一个文件就够,不用读源码
|
||||
|
||||
### 测试
|
||||
|
||||
82 → 84 单测全过:原 Option 3 的 11 个测试改成验 Option 2(envelope 必带 key / 无 shape / head units&version / objects 1:1 / BBox min-max / 内层 SIGNAL append / docType reject)。
|
||||
|
||||
### Push
|
||||
|
||||
`fe6971f` 的 Option 3 已被这次 commit 覆盖 / 简化掉。下游回来如果说 mapping table 有错位再修——但他自己拿表填 adapter,跑通后给反馈我们再迭代。
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-29 04:00 Std-format JSON 转换器:EPRO2 → 下游同学 Wokwi pipeline 的输入格式
|
||||
|
||||
**Claude 会话**
|
||||
|
||||
Reference in New Issue
Block a user