返回作品

AI 工具 · A2

CAD 零件信息提取、BOM 整理与图纸批量导出

读取 STEP 装配体,提取零件属性并估算质量,检查零件号与材料,一次输出 BOM、问题清单和每个零件的三视图。

个人自主项目2026年10月制作的公开演示,使用自建的通用模型方法与需求定义、结果核对由本人负责;代码由 AI 编码工具实现,并经本人审核工作中针对 CATIA 的同类工具因保密不公开,本页不展示 CATIA 运行

一次运行的结果

零件种类
17
零件实例
32
三视图图纸
17
发现问题
54 条错误 · 1 条警告
总耗时
3.84s

沙箱 Linux x86_64,2 个 vCPU,Python 3.13.16,OCP 7.8.1.1

处理流程

  1. STEP 装配

    中性格式 STEP AP242。PRODUCT 的 id 作零件号、name 作名称;材料写在 AP242 材料属性里。

    input/*.step
  2. 装配树遍历

    按产品定义递归展开子装配,累计每个零件的实例数量与位置。

    step_reader.py
  3. 属性与质量

    对精确 B-rep 积分得到体积与表面积,取包围盒;体积 × 密度表得到估算质量。

    geometry.py
  4. 规则检查

    零件号正则与规范化、缺材料、材料不在密度表、重复零件号(比较几何)、实体有效性。

    rules.py
  5. BOM · 三视图 · 文件名

    BOM 输出 CSV / XLSX / JSON;HLR 投影生成 A4 三视图;文件名统一为「零件号_名称」。

    report.py · drawing.py · naming.py

输入:示例装配体

示例机器人关节装配体的四分之一剖切渲染,可见电机、谐波减速单元与轴承
四分之一剖切渲染(由 STEP 曲面三角化后渲染,仅用于展示)

通用机器人关节的简化结构:中空电机、谐波减速单元、交叉滚子轴承、端盖与紧固件,含电机与减速器 2 个子装配。尺寸为演示用的整数占位值,与任何产品无关。由同目录的 Python 脚本用 OpenCASCADE 参数化建模后导出为 STEP。

为验证规则检查,示例数据中故意写错了 4 处:

  1. 前端盖沿用后端盖的零件号 RJ-STR-002
  2. 驱动板零件号写成 rj_elc_002(只有大小写与分隔符不对)
  3. 编码器码盘没有指定材料
  4. M3×8 螺栓零件号写成 RJ-FST-02(位数不对)

问题清单

规则检查的原始输出(issues.csv),按严重度排序。重复零件号对两个零件各记一条。

级别零件号名称说明
错误RJ-ELC-001编码器码盘未指定材料,未估算质量
错误RJ-FST-02六角螺栓 M3×8零件号「RJ-FST-02」不符合命名规则,未自动修改:位数不对时无法判断应补成哪个号,需人工确认
错误RJ-STR-002前端盖零件号 RJ-STR-002 被 2 个几何不同的零件共用(后端盖、前端盖)
错误RJ-STR-002后端盖零件号 RJ-STR-002 被 2 个几何不同的零件共用(后端盖、前端盖)
警告RJ-ELC-002驱动板零件号「rj_elc_002」只有大小写或分隔符不规范,已规范为 RJ-ELC-002

BOM

汇总 BOM,共 17 行。表格在点击后才读取 bom.json;列标题可排序。

下载

三视图图纸

每个零件一张 A4 图纸(SVG),第一角法,按零件号命名。线条由 OpenCASCADE 隐藏线消除(HLR)投影得到,只标外形尺寸。点击查看大图。

Python 工具

工具位于仓库 tools/cad-bom/:几何内核为开源的 OpenCASCADE(cadquery-ocp),BOM 表格用 openpyxl,依赖版本固定在 requirements.txt。下面的数字来自提交的 output/run.json;除耗时外,pytest 会重跑并逐字节比对输出。

分阶段耗时

阶段秒
读取 STEP 与装配树0.25
体积、表面积、包围盒0.14
规则检查0.00
汇总 BOM0.00
写 CSV / XLSX0.02
三视图(HLR)2.53
装配总览图0.91
清单与校验和0.00
总耗时3.84

复现

cd tools/cad-bom
python -m venv .venv
.venv/bin/pip install -r requirements.txt
.venv/bin/python -m cadbom input/robot-joint-demo.step
.venv/bin/python -m pytest

对比:手工做同样的事,需要逐个打开零件查看属性、测量体积、核对零件号,再逐张出图并重命名;工具一次运行完成,且结果可重复核对。

核心代码

遍历装配树(step_reader.py)
def walk(label: TDF_Label, location: TopLoc_Location, depth: int) -> Occurrence:
    node = Occurrence(definition(label), location, depth)
    if XCAFDoc_ShapeTool.IsAssembly_s(label):
        components = TDF_LabelSequence()
        XCAFDoc_ShapeTool.GetComponents_s(label, components, False)
        for i in range(1, components.Length() + 1):
            component = components.Value(i)
            referred = TDF_Label()
            XCAFDoc_ShapeTool.GetReferredShape_s(component, referred)
            placement = location.Multiplied(XCAFDoc_ShapeTool.GetLocation_s(component))
            node.children.append(walk(referred, placement, depth + 1))
    return node
零件号检查与规范化(rules.py)
def check_part_number(raw: str | None, name: str, pattern: str) -> Checked:
    if raw is None:
        return Checked("", [Issue("PN_AMBIGUOUS", "", name, {})])
    regex = re.compile(pattern)
    if regex.fullmatch(raw):
        return Checked(raw, [])
    fixed = normalize_part_number(raw)
    if regex.fullmatch(fixed):
        return Checked(fixed, [Issue("PN_NORMALIZED", fixed, name, {"raw": raw, "fixed": fixed})])
    return Checked(raw, [Issue("PN_FORMAT", raw, name, {"raw": raw, "pattern": pattern})])
HLR 投影出视图(drawing.py)
def project(shape: TopoDS_Shape, view: str, deflection: float = 0.02, hidden: bool = True) -> Projection:
    direction, x_dir = VIEWS[view]
    algo = HLRBRep_Algo()
    algo.Add(shape)
    algo.Projector(HLRAlgo_Projector(gp_Ax2(gp_Pnt(0, 0, 0), gp_Dir(*direction), gp_Dir(*x_dir))))
    algo.Update()
    algo.Hide()
    result = HLRBRep_HLRToShape(algo)
    visible = _polylines(result.VCompound(), deflection) + _polylines(result.OutLineVCompound(), deflection)
    hidden_lines = []
    if hidden:
        hidden_lines = _polylines(result.HCompound(), deflection) + _polylines(
            result.OutLineHCompound(), deflection)
    return Projection(visible, hidden_lines)

与 CATIA 自动化的对应

工作中做过针对 CATIA 的同类工具(VBA / Python 调用 CATIA 自动化接口),因保密不公开。下表只用文字说明本页每一步在 CATIA V5 对象模型中对应的概念;本页没有运行 CATIA,也不提供 CATIA 宏代码。

本页(STEP + OpenCASCADE)CATIA V5 自动化中的对应概念
XCAF 装配树、组件与位置ProductDocument → Product.Products(实例)与 ReferenceProduct
STEP PRODUCT 的 id / nameProduct.PartNumber / Product.Nomenclature
AP242 材料与密度表零件上应用的材料及其密度,或自定义 Parameters
BRepGProp 体积、表面积SPAWorkbench 的 Measurable(Volume、Area)或 Product.Analyze
HLR 三视图 SVGDrawingDocument 中生成视图,再用 ExportData 导出 PDF / DXF
「零件号_名称」文件名按 PartNumber 等属性重命名并另存文档

限制

  • 示例装配是自建的通用模型,结构经过简化(齿形、滚动体未建模),不代表任何产品。
  • 质量 = 体积 × 名义密度,是估算值;不含涂层、螺纹、公差与装配件内部结构。
  • 三视图是 HLR 投影示意:只标外形尺寸(包围盒),没有公差、剖视与细部尺寸,不能直接用于加工。
  • 演示基于 STEP 与 OpenCASCADE,没有在 CATIA 中运行;CATIA 中对应的接口见上表,仅作概念说明。

项目要点

问题
零件多、命名不统一时,如何从三维装配一次得到可核对的 BOM、问题清单与图纸?
方法
遍历 STEP 装配树取零件号、名称、材料与实例数;在 B-rep 上积分得体积并按密度表估算质量;用正则与几何比较做规则检查;HLR 投影批量生成三视图,并按「零件号_名称」统一命名。
结论
示例装配 17 种零件、32 个实例,一次运行输出 BOM(CSV / XLSX)与 17 张三视图;预置的 4 处数据错误全部检出(重复零件号涉及 2 个零件,共 5 条记录)。