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?

ブロック作品を LeoCAD でつくる4 〜発注その2/submodel ごとのパーツリストを作る〜

Last updated at Posted at 2025-08-30

「ブロック作品を LeoCAD でつくる3 〜発注その1〜」
https://qiita.com/nanbuwks/items/2208a73c6f9a9787c856
の続きです。

前回は、CAD に落とし込んだ4階建てエレベーターから CSV のパーツリストを作って発注を行いましたが、
パーツが約2100 pcs、種類も約300 の作業を行うにあたっていろいろと問題がありました。

  • カートに入れるのが大変。間違いや漏れが多々発生する
  • 組み立て時に部分ごとにパーツが別れた状態でないと日効率

今回はこれを解決するための方法を考えます。

submodel

以下のようにLeoCAD内では submodel に分けて管理をしています。

image.png

一番上の whole.ldr が全体構成です。

image.png

submodel 単位で発注を行い、パーツを分けて組み立てて行きたいですね。

image.png

上記表示では Machine1.ldr という名前がついていて、いかにもファイル名ぽいですがこのままだとこのサブモジュールのパーツの把握ができません。

Timeline でパーツのリストが出てきますが、パーツ番号などは表示されず役に立たないです。

image.png

Submodels 画面から、Exportを行うい、それぞれを読み込み直して CSV にエクスポートすればなんとかなるかも知れませんが、 Submodel が多いと手間がかかって仕方が無いですね!

ldr フォーマット

LeoCAD のファイルは ldr 形式なのですが、中身はテキストとして読める形式です。今回のブロックエレベータの ldr ファイルは以下のようになってました。

0 FILE whole.ldr
0 
0 Name: whole.ldr
0 Author: 
1 7 420 -800 300 0 0 -1 0 1 0 1 0 0 weights.ldr
1 7 20 -460 -180 1 0 0 0 1 0 0 0 1 kagos.ldr
1 7 3 0 1 1 0 0 0 1 0 0 0 1 Frames.ldr
1 295 151 -1470 -160 -1 0 0 0 1 0 0 0 -1 Machines.ldr
1 7 37 -198 -122 -1 0 0 0 1 0 0 0 -1 Floor1F.ldr
1 7 37 -518 -122 -1 0 0 0 1 0 0 0 -1 Floor2F.ldr
1 7 37 -818 -122 -1 0 0 0 1 0 0 0 -1 Floor3F.ldr
1 7 37 -1158 -122 -1 0 0 0 1 0 0 0 -1 Floor4F.ldr
0 NOFILE
0 FILE Frames.ldr
0 
0 Name: Frames.ldr
0 Author: 
1 7 0 -1 -1 1 0 0 0 1 0 0 0 1 KagoWeightSwitchRail.ldr
0 !LEOCAD PIECE PIVOT  130 -176 470 1 0 0 0 1 0 0 0 1
.
.
.
1 7 118.8387 -586.0504 250 -0.882948 0 -0.469472 0.469472 0 -0.882948 0 -1 0 Back-Frame1.ldr
1 7 -123.8575 -556.2504 252 -0.882948 0 0.469471 -0.469472 0 -0.882948 0 -1 0 back-Frame2.ldr
1 7 326 -1173.2727 260.7273 0 0 -1 0 1 0 1 0 0 6541.dat
1 7 306 -1148 261 0 0 1 0 1 0 -1 0 0 63325.dat
1 7 326 -1140.2727 260.7273 0 0 -1 0 1 0 1 0 0 63326.dat
1 7 326 -1087.2727 260.7273 0 0 -1 0 1 0 1 0 0 6541.dat
1 7 306 -1096 261 0 0 1 0 1 0 -1 0 0 63325.dat
1 7 326 -1104.2727 260.7273 0 0 -1 0 1 0 1 0 0 63326.dat
1 7 336 -1162.2727 260.7273 1 0 0 0 1 0 0 0 1 32002.dat
1 7 336 -1079.2727 260.7273 1 0 0 0 1 0 0 0 1 32002.dat
1 7 341 -1121.2727 259.7273 0 -1 0 0 0 -1 1 0 0 32017.dat
1 7 326 -532.2727 260.7273 0 0 -1 0 1 0 1 0 0 6541.dat
1 7 306 -507 261 0 0 1 0 1 0 -1 0 0 63325.dat
.
.
.

ふむ、これは CSV として読んだらうまく加工できそうです。

image.png

.
.
.

image.png

B列が色コードです。

色コード例

0 Black
1 Blue
2 Green
4 Red
5 Dark Pink
7 Light Grey
10 Bright Green
12 Salmon
15 White
18 Light Yellow
25 Orange
47 Trans Clear
134 Copper
226 Bright Light Yellow

csv を Spreadsheet に読み込んで手作業をすれば submodel ごとの パーツリストが作れそう・・・ですが手作業がメンドクサイので、python で csv を作るようにしてみました。

python プログラム

chatGPT で作ったもののに手を加えて、以下のようなものを作りました。

2025-9-10 改訂:当初のものはカラーマップがデタラメでした。修正しています。

#!/bin/env python3
import os
import csv
from collections import defaultdict

# 色のマッピング(仮定)
COLOR_MAP = {
    '0': 'Black',
    '1': 'Blue',
    '2': 'Green',
    '3': 'Dark_Turquoise',
    '4': 'Red',
    '5': 'Dark_Pink',
    '6': 'Brown',
    '7': 'Light_Gray',
    '8': 'Dark_Grey',
    '9': 'Light_Blue',
    '10': 'Bright_Green',
    '11': 'Light_Turquoise',
    '12':'Salmon',
    '15': 'White',
    '16': 'Main_Colour',
    '18': 'Light Yellow',
    '23': 'Dark_Blue_Violet',
    '25': 'Orange',
    '47': 'Trans Clear',
    '134':'Copper',
    '226':'Bright Light Yellow',
    '368':'Vibrant Yellow'

    '3': 'Light Gray',
    '4': 'White',
    '5': 'Red',
    '6': 'Bright Green',
    '7': 'Blue',
    '8': 'Yellow',
    '9': 'Tan',
    '10': 'Dark Brown',
    '11': 'Light Brown',
    '16': 'Dark Blue',
    '23': 'Bright Light Orange',
    '12':'Salmon',
    '15':'White',
    '18':'Light Yellow',
    '25':'Orange',
    '47':'Trans Clear',
    '134':'Copper',
    '226':'Bright Light Yellow',
    '368':'Vibrant Yellow'

# 必要に応じて追加
}

def parse_ldr_file(filepath):
    submodels = {}
    current_model = None
    parts = defaultdict(list)

    with open(filepath, 'r', encoding='utf-8') as file:
        for line in file:
            line = line.strip()

            if line.startswith("0 FILE"):
                current_model = line.split(" ", 2)[2]
                if current_model not in parts:
                    parts[current_model] = []
            elif line.startswith("1 ") and current_model:
                tokens = line.split()
                part_name = tokens[-1]  # 最後のトークンが部品名(例: 3001.dat)
                color_code = tokens[1]  # 2番目のトークンがカラーコード
                parts[current_model].append((part_name, color_code))

    # サブモデル名 -> パーツの出現回数とカラーコード(辞書)
    submodel_parts = {}
    for model_name, part_list in parts.items():
        part_counts = defaultdict(lambda: defaultdict(int))  # {part_name: {color_code: count}}
        for part_name, color_code in part_list:
            part_counts[part_name][color_code] += 1
        submodel_parts[model_name] = part_counts

    return submodel_parts

def export_to_csv(submodel_parts, output_dir):
    os.makedirs(output_dir, exist_ok=True)

    for model_name, parts in submodel_parts.items():
        base_name = os.path.splitext(model_name)[0]
        csv_filename = os.path.join(output_dir, f"{base_name}.csv")

        with open(csv_filename, 'w', newline='', encoding='utf-8') as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(['Part Name', 'Color Code', 'Color Name', 'Quantity'])

            for part_name, color_counts in sorted(parts.items()):
                if part_name.endswith('.ldr'):
                    continue
                for color_code, count in sorted(color_counts.items()):
                    color_name = COLOR_MAP.get(color_code, 'Unknown')
                    writer.writerow([part_name.rstrip('.dat'), color_code, color_name, count])

        print(f"✅ Exported: {csv_filename}")

def main():
    input_ldr_file = "20250521.ldr"  # <- ここを処理したい LDR ファイルに変更
    output_folder = "output_parts_with_colors"

    submodel_parts = parse_ldr_file(input_ldr_file)
    export_to_csv(submodel_parts, output_folder)

if __name__ == "__main__":
    main()


できたcsvファイルです。

$  ls output_parts_with_colors/

 12FBoardHolder.csv   Floor3F.csv                        LEFT-RIGHT-Back-VerticalRF.csv  'Merged Floor202409.csv'        Vertical-Frame234F.csv   kago-4.csv     kagos.csv       wire.csv
 34FBoardHolder.csv   Floor4F.csv                        Left-Frame1F.csv                 Right-Frame1F.csv              Vertical-FrameRF.csv     kago-5.csv     parts.csv
'BASE&1F.csv'         Frames.csv                         Left-Frame234F.csv               Right-Frame234F.csv            back-Frame2.csv          kago-6か.csv   weight1.csv
 Back-Frame1.csv      Front-RF.csv                       Left-FrameRF.csv                 Right-FrameRF.csv              back-frame-rf.csv        kago-7.csv     weight2.csv
 Floor.csv            KagoWeightSwitchRail.csv           Machine1.csv                     Vertical-Frame-Composite.csv   back-frame.csv           kago1.csv      weight3う.csv
 Floor1F.csv          LEFT-RIGHT-Back-Vertical1F.csv     Machine2.csv                     Vertical-Frame1F.csv           base-Frame.csv           kago2.csv      weights.csv
 Floor2F.csv          LEFT-RIGHT-Back-Vertical234F.csv   Machines.csv                     Vertical-Frame2.csv            kago-3.csv               kago6.csv      whole.csv

$ cat output_parts_with_colors/12FBoardHolder.csv 

Part Name,Color Code,Color Name,Quantity
32278,7,Blue,2
32316,7,Blue,1
32523,7,Blue,1
32556,7,Blue,4
3704,7,Blue,4
42003,7,Blue,2
4459,7,Blue,10
6632,7,Blue,2


これを元に、発注していきます。

今回は、タオバオで発注してみました。

Chat とメールを併用して交渉。

image.png

カスタム設計部品注文用に用意されているアイテムで値段を合わせて注文します。

image.png

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?