0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

STEPから部品リストを自動で抜くスクリプトを書いてみた

0
Posted at

STEPから部品リストを自動で抜くスクリプトを書いてみた

設計変更のたびに部品リストを手入力していないですか。

CADを開いて、アセンブリの部品一覧をスクショして、Excelに手入力する。
100部品を超えたらコピペでも振り分けに時間がかかる。
同じ部品名でも何度も入力し直すし、誰かが修正したら、それをまた反映させるのに時間がかかる。

その間に転記ミスも出る。
検図すると、「部品数が合わない」って事もちらほら。

「何かこれを自動化できないか」と思って、PythonでSTEPファイルから部品情報を抽出して、そのままExcelに落とすスクリプトを書いてみました。

前の記事で説明したこと

STEPファイルをPythonで読み込む基本的な方法は、前の記事で説明しています。

この記事では、BOM生成に特有の処理 — 部品情報の抽出とExcel出力 — に絞ります。

アセンブリから部品情報を抽出する

アセンブリのSTEPを読むと、複数のソリッド(部品)が入ってます。

import cadquery as cq
import re

def load_part_names(step_path):
    """STEPファイルのテキストから部品名を抽出"""
    with open(step_path, "r", encoding="utf-8", errors="ignore") as f:
        text = f.read()

    products = re.findall(r"PRODUCT\s*\(\s*'([^']+)'", text)
    # ルートアセンブリ(UUID形式)は除外
    names = [p for p in products if not (len(p) == 36 and p.count("-") == 4)]
    return names

def extract_bom(step_path):
    """STEPからBOM(部品リスト)を抽出"""
    result = cq.importers.importStep(step_path)
    shape = result.val()  # Compoundを取得
    solids = shape.Solids()  # OCCのShapeリスト
    names = load_part_names(step_path)

    # 部品名が足りない場合は自動採番
    while len(names) < len(solids):
        names.append(f"Part_{len(names)+1:03d}")

    bom = []
    for i, solid in enumerate(solids):
        bb = solid.BoundingBox()
        bom.append({
            "部品番号": i + 1,
            "部品名": names[i],
            "数量": 1,
            "外形_X": round(bb.xlen, 2),
            "外形_Y": round(bb.ylen, 2),
            "外形_Z": round(bb.zlen, 2),
            "体積_mm3": round(solid.Volume(), 1),
            "面数": len(solid.Faces()),
        })

    return bom

実行するとこんなリストが出ます。

bom = extract_bom("assembly.step")
for item in bom:
    print(item)
{'部品番号': 1, '部品名': 'Bracket_001', '数量': 1, '外形_X': 45.23, ...}
{'部品番号': 2, '部品名': 'Shaft_002', '数量': 1, '外形_X': 150.00, ...}

ExcelにBOMを出力する

ここが今回の本題。openpyxlを使ってExcelファイルを自動生成します。

pip install cadquery openpyxl
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side

def write_bom_to_excel(bom, output_path="BOM.xlsx"):
    """BOMをExcelファイルに書き込む"""
    wb = Workbook()
    ws = wb.active
    ws.title = "BOM"

    # ヘッダー
    headers = ["部品番号", "部品名", "数量", "外形_X(mm)", "外形_Y(mm)", "外形_Z(mm)", "体積(mm³)", "面数"]
    ws.append(headers)

    # ヘッダーのスタイル
    header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
    header_font = Font(bold=True, color="FFFFFF")
    for cell in ws[1]:
        cell.fill = header_fill
        cell.font = header_font
        cell.alignment = Alignment(horizontal="center")

    # データ行
    for item in bom:
        ws.append([
            item["部品番号"],
            item["部品名"],
            item["数量"],
            item["外形_X"],
            item["外形_Y"],
            item["外形_Z"],
            item["体積_mm3"],
            item["面数"],
        ])

    # 列幅
    ws.column_dimensions["A"].width = 10
    ws.column_dimensions["B"].width = 20
    ws.column_dimensions["C"].width = 8
    for col in ["D", "E", "F", "G", "H"]:
        ws.column_dimensions[col].width = 14

    # 枠線
    thin_border = Border(
        left=Side(style="thin"), right=Side(style="thin"),
        top=Side(style="thin"), bottom=Side(style="thin"),
    )
    for row in ws.iter_rows(min_row=1, max_row=len(bom) + 1, min_col=1, max_col=8):
        for cell in row:
            cell.border = thin_border

    wb.save(output_path)
    print(f"BOM exported to {output_path}")

これで実行。

bom = extract_bom("assembly.step")
write_bom_to_excel(bom, "BOM_output.xlsx")

ヘッダーは青背景、枠線付きのExcelが出てくる。数十部品のアセンブリなら5秒で終わる。

実務での使い方

自分はこんな感じで回してます。

  1. CADで修正したアセンブリをSTEPで出す
  2. 旧版と新版のSTEPを比較して、何が変わったかを確認
  3. 新版のSTEPを上のスクリプトに投げる
  4. Excelが自動生成される
  5. 部品数や名前に漏れがないかをさっと確認して提出

手作業で転記してた頃は30分〜1時間かかってたので、これが自動化できたらだいぶ楽?
修正がたびたび入るときに、そのたびにBOMを生成し直せるのが地味にありがたい。

注意点

部品名の対応が厄介。
CadQueryには部品名を取るAPIがないので、STEPのテキストを正規表現で抜いてます。
設変前後で部品名が変わると別物扱いになる。
同じCADから出したSTEPなら順序は大体変わらないので、実用上はこれで足りてるかなと。

大きいアセンブリは時間がかかる。
実測で約5秒/MB。
30MBのSTEPだと2分くらい。

サーフェスボディは未対応。
製造業のSTEPはほぼソリッドなので、今のところ問題にはなってない。


こういうスクリプトの応用で、STEPの差分比較や3Dビューアも組み合わせたツールを作ってみてます。興味があれば覗いてみてください。

ドコカワ v1.0(Windows用・無料)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?