|
|
# dxf2elmt
|
|
|
|
|
|
`dxf2elmt` 是一个把 ASCII 或二进制 DXF 图纸转换为
|
|
|
[QElectroTech](https://qelectrotech.org/) `.elmt` 元件文件的命令行工具。
|
|
|
|
|
|
源项目地址:<https://github.com/qelectrotech/dxf2elmt_vadoola>
|
|
|
|
|
|
## 编译
|
|
|
|
|
|
项目使用 Rust,最低支持版本(MSRV)为 1.79.0。
|
|
|
|
|
|
```bash
|
|
|
cargo build --release
|
|
|
```
|
|
|
|
|
|
编译后的程序位于:
|
|
|
|
|
|
```text
|
|
|
target/release/dxf2elmt.exe
|
|
|
```
|
|
|
|
|
|
## 使用方法
|
|
|
|
|
|
转换一个或多个 DXF 文件:
|
|
|
|
|
|
```bash
|
|
|
dxf2elmt drawing.dxf
|
|
|
dxf2elmt first.dxf second.dxf
|
|
|
```
|
|
|
|
|
|
输出文件与输入 DXF 位于同一目录,文件名不变,仅将扩展名改为 `.elmt`。
|
|
|
|
|
|
常用参数:
|
|
|
|
|
|
| 参数 | 作用 |
|
|
|
| --- | --- |
|
|
|
| `-v`, `--verbose` | 不写入 `.elmt` 文件,改为把 XML 输出到标准输出 |
|
|
|
| `-s`, `--spline-step <N>` | 设置 SPLINE 的折线细分数量,默认值为 20;数值越大越平滑 |
|
|
|
| `-i`, `--info` | 输出实体统计和转换耗时 |
|
|
|
| `-d`, `--dtext` | 当前为保留参数;现有实现始终把 TEXT/MTEXT 转为动态文本 |
|
|
|
|
|
|
查看完整参数:
|
|
|
|
|
|
```bash
|
|
|
dxf2elmt --help
|
|
|
```
|
|
|
|
|
|
## 当前实体映射
|
|
|
|
|
|
| DXF 实体 | ELMT 图元 | 当前处理方式 |
|
|
|
| --- | --- | --- |
|
|
|
| `LINE` | `<line>` | 保留两个端点、颜色、线型和数值线宽 |
|
|
|
| `CIRCLE` | `<ellipse>` | 以等宽、等高椭圆表示圆 |
|
|
|
| `ARC` | `<arc>` | 保留圆心、半径、起始角和圆弧角度 |
|
|
|
| `ELLIPSE` | `<ellipse>` | 转换中心、长轴和短长轴比例 |
|
|
|
| `POLYLINE` | `<line>` / `<ellipse>` / `<polygon>` | 两个顶点转直线;识别为圆时转椭圆;其余转多边形 |
|
|
|
| `LWPOLYLINE` | `<line>` / `<arc>` / `<ellipse>` / `<polygon>` | 根据顶点数、圆形特征和 bulge 分别处理,详细规则见下文 |
|
|
|
| `SPLINE` | `<polygon>` | 按 `spline-step` 采样为折线,不保留参数曲线本身 |
|
|
|
| `SOLID` | 填充 `<polygon>` | 按 DXF 的 `1-2-4-3` 顶点顺序恢复边界并填充 |
|
|
|
| `TRACE` | 填充 `<polygon>` | 与 SOLID 相同,按四边形边界转换并填充 |
|
|
|
| `TEXT` | `<dynamic_text>` | 转换内容、位置、旋转、字号、宽度系数和对齐方式 |
|
|
|
| `MTEXT` | `<dynamic_text>` | 部分支持,转换内容、位置、方向、字号和对齐方式 |
|
|
|
| `ATTDEF`(属性定义) | `<dynamic_text>` | 转换属性标签及其文本样式和位置 |
|
|
|
| `LEADER` | 一组 `<line>` | 相邻顶点生成线段,首段可带箭头 |
|
|
|
| `INSERT` | 块实例或 `<terminal>` | 普通 INSERT 展开块;特定连接点块转为端子 |
|
|
|
|
|
|
未列出的实体当前不会生成 ELMT 图元。
|
|
|
|
|
|
### LWPOLYLINE 映射规则
|
|
|
|
|
|
- 两个顶点且第一个顶点 `bulge != 0`:转换为圆弧。
|
|
|
- 两个顶点且没有 bulge:转换为直线。
|
|
|
- 多个顶点且整体被识别为圆:转换为椭圆。
|
|
|
- 同时包含直线段和 bulge 圆弧段:按段拆分为多个 `<line>` 和 `<arc>`,避免圆弧丢失。
|
|
|
- 其他情况:转换为 `<polygon>`。
|
|
|
- 开放多段线不会把最后一个顶点错误连接回第一个顶点;闭合多段线会保留闭合段。
|
|
|
|
|
|
## 样式映射
|
|
|
|
|
|
### 线宽
|
|
|
|
|
|
ELMT 只输出数值字段 `line-width-mm`,不再输出旧的
|
|
|
`line-weight:thin/normal/...` 档位。
|
|
|
|
|
|
LW 当前提供以下毫米预设值:
|
|
|
|
|
|
```text
|
|
|
0.00, 0.05, 0.09, 0.13, 0.15, 0.18, 0.20, 0.25,
|
|
|
0.30, 0.35, 0.40, 0.50, 0.53, 0.60, 0.70, 0.80,
|
|
|
0.90, 1.00, 1.06, 1.20, 1.40, 1.58, 2.00, 2.11 mm
|
|
|
```
|
|
|
|
|
|
默认值为 `0.25 mm`。转换器得到毫米线宽后,会按 LW 的
|
|
|
`normalizedMillimeters` 规则选择距离最近的预设值,例如
|
|
|
`0.33 → 0.35 mm`、`0.68 → 0.70 mm`。超出范围的值会归一到最接近的端点预设。
|
|
|
|
|
|
线宽来源和优先级如下:
|
|
|
|
|
|
1. `LWPOLYLINE.constant_width` 大于 0 时,作为该图元的宽度来源。
|
|
|
2. 否则读取第一个顶点的 `starting_width` 或 `ending_width`。
|
|
|
3. 没有多段线宽度时,读取 DXF 实体公共组码 370 `line_weight`,其非负值按 `1/100 mm` 转换,例如 `35` 得到 `0.35 mm`。
|
|
|
4. `BYLAYER`、`BYBLOCK`、`DEFAULT` 等负值当前不会被伪造成固定线宽,也不会输出 `line-width-mm`。
|
|
|
5. 对得到的毫米值执行 LW 预设归一化,再输出 `line-width-mm`。
|
|
|
|
|
|
DXF 组码 39 的 `thickness` 是沿挤出方向的三维厚度,不是二维描边宽度。
|
|
|
转换器不会用 `thickness` 计算 `line-width-mm`。
|
|
|
|
|
|
### 线型
|
|
|
|
|
|
以下 DXF 线型名称会转换为 ELMT 虚线:
|
|
|
|
|
|
- 名称中包含 `DASH`
|
|
|
- `BORDURE`
|
|
|
- `INTERROMPU`
|
|
|
- `INTERROMPUx2`
|
|
|
- `TRACECAD_ISO02W100`
|
|
|
|
|
|
其他线型目前按普通实线处理,不解析 DXF 线型的具体线段和空隙图案。
|
|
|
|
|
|
### 颜色
|
|
|
|
|
|
- `LINE`、`ARC`、`LWPOLYLINE`、`TEXT` 和属性文本会优先读取 ACI 颜色索引,否则读取 24 位真彩色。
|
|
|
- 部分通过几何识别生成的图元仍使用黑色默认值,例如部分 `CIRCLE`、`ELLIPSE`、`POLYLINE`、`SPLINE`、`SOLID` 和 `TRACE` 路径。
|
|
|
- `BYLAYER` 和 `BYBLOCK` 颜色尚未完整解析其最终继承值。
|
|
|
|
|
|
## 坐标、单位和二维化
|
|
|
|
|
|
- DXF Y 轴会翻转以适配 ELMT 坐标方向。
|
|
|
- 图形会根据 DXF 头部的 `default_drawing_units` 缩放;无单位图纸暂不缩放。
|
|
|
- 当前毫米图纸使用代码中的 `3.78` 缩放因子。
|
|
|
- 转换完成后,元件图形会以自身包围盒为依据移动到局部坐标中心。
|
|
|
- INSERT 会应用块基点、插入位置、X/Y 缩放和旋转。
|
|
|
- ELMT 元件是二维图形,因此图元 Z 坐标、挤出方向和 `thickness` 不会转换成三维模型。
|
|
|
|
|
|
## 块和端子
|
|
|
|
|
|
- 被 INSERT 引用的 DXF 块会写入 ELMT 的 `<blocks>` 定义。
|
|
|
- 普通 INSERT 会展开为带 `block_name` 和 `block_instance` 元数据的块实例图元。
|
|
|
- 嵌套块可以递归转换;序列化时内部图元使用最外层有效实例元数据。
|
|
|
- 名称为 `ARROWUNKNOWN` 且带有 `connector` 属性的 INSERT 会转换为
|
|
|
QElectroTech `<terminal>`,属性值同时用于端子名称和连接点标签。
|
|
|
- 名称为 `ORIENT` 的辅助图层会跳过,不导出定位标记。
|
|
|
|
|
|
## 已知限制
|
|
|
|
|
|
- `HATCH`、`DIMENSION`、`3DFACE`、`MESH` 等未实现实体会被跳过。
|
|
|
- 不支持真正的三维符号;3D 数据只保留可转换的二维 XY 投影。
|
|
|
- `LWPOLYLINE` 的逐段可变宽度尚未完整表达。目前会取第一个顶点的非零起始或结束宽度,并把它应用到整个转换结果。
|
|
|
- `LWPOLYLINE` 的几何宽度当前直接写入毫米字段,因此非毫米 DXF 的宽度还需要补充单位换算。
|
|
|
- 组码 370 的 `BYLAYER` / `BYBLOCK` 线宽尚未解析图层或父块的继承值。
|
|
|
- MTEXT 的内联格式、复杂字体替换、段落布局和背景框尚未完整支持。
|
|
|
- `--dtext` 当前不会改变行为,TEXT 和 MTEXT 都默认输出动态文本。
|
|
|
- 深层嵌套块、非均匀缩放后的圆弧以及复杂镜像仍需要更多样图验证。
|
|
|
- 当前错误信息较少,部分不支持的实体会被静默忽略。
|
|
|
|
|
|
## DXF 诊断工具
|
|
|
|
|
|
必要时可使用 `dxf2json.exe` 把 DXF 转换为 JSON,以检查实体、块、属性、
|
|
|
对齐方式、颜色、坐标、bulge 和宽度数据。
|
|
|
|
|
|
```bash
|
|
|
dxf2json drawing.dxf
|
|
|
```
|
|
|
|
|
|
## 测试
|
|
|
|
|
|
```bash
|
|
|
cargo test
|
|
|
```
|
|
|
|
|
|
当前回归测试覆盖 XRECORD 清理、端子语义、块实例、嵌套块、SOLID 填充、
|
|
|
混合 LWPOLYLINE 圆弧拆分、负 bulge 圆弧方向以及数值线宽转换。
|
|
|
|
|
|
## 待办事项
|
|
|
|
|
|
- 支持剩余二维实体。
|
|
|
- 完善图层、块和尺寸样式继承。
|
|
|
- 完善非毫米图纸的多段线宽度换算。
|
|
|
- 改进错误信息和日志输出。
|
|
|
|
|
|
## Credits
|
|
|
|
|
|
- [Antonioaja](https://github.com/antonioaja) 创建了最初版本的
|
|
|
[dxf2elmt](https://github.com/antonioaja/dxf2elmt)。
|
|
|
- [QElectroTech](https://qelectrotech.org/)
|
|
|
- [dxf-rs](https://github.com/IxMilia/dxf-rs)
|
|
|
- [simple-xml-builder](https://github.com/Accelbread/simple-xml-builder)
|
|
|
- [bspline](https://github.com/Twinklebear/bspline)
|
|
|
- [tempfile](https://github.com/Stebalien/tempfile)
|