Generate 3D CAD models (STEP/STL) and multi-view renders from a declarative JSON intermediate representation, built on build123d.
Project description
cad-tools
宣言的な JSON(semantic IR)から build123d で 3D CAD モデルを生成し、STEP / STL 出力と 4 ビュー PNG レンダリングを行う Python ライブラリ。
命令的な CAD コードではなく「どんな形状か」を JSON で記述するだけでモデルが組み上がる。 AI エージェントが MCP 経由で形状を反復設計することを主眼に設計している。
上図はサンプル
examples/l_bracket.pyの出力。ISO / 正面 / 上面 / 右側面の 4 ビュー。
特長
- 宣言的な IR — プリミティブ・穴・面取り・中空などを JSON で組み合わせるだけ
- 相対配置 — 既存形状の面中心・角・中心(アンカー)を基準に部品を置ける
- headless レンダリング — VTK / PyVista による GUI 不要の 4 ビュー描画(CAD 風の輪郭付き)
- MCP サーバ — エージェントが「IR を渡す → 画像が返る」ループで設計を反復できる
- 標準フォーマット出力 — STEP(CAD)/ STL(メッシュ)/ PNG(確認用)
インストール
Python 3.12 が必要。uv を推奨する。
uv add cad-tools
pip の場合:
pip install cad-tools
GUI / GPU の無い環境(コンテナ・CI)では、描画時に Xvfb 仮想ディスプレイを自動起動する。 Linux では
Xvfbがインストールされていること(例:apt-get install xvfb)。
クイックスタート
from cad_tools import Build123dEmitter, render_part
ir = {
"features": [
{"id": "base", "type": "box", "size": [40, 30, 10]},
{"id": "post", "type": "cylinder", "radius": 5, "height": 20,
"reference": {"feature": "base", "anchor": "top_face_center"}},
{"id": "hole", "type": "hole", "target": "base", "diameter": 6, "depth": 10,
"reference": {"feature": "base", "anchor": "top_face_center"}},
]
}
part = Build123dEmitter(ir).build() # build123d の Solid を返す
render_part(part, "render.png") # 4 ビュー PNG を書き出す
STEP / STL に出力するには build123d の関数をそのまま使える:
from build123d import export_step, export_stl
export_step(part, "part.step")
export_stl(part, "part.stl")
公開 API
from cad_tools import (
Build123dEmitter, # IR から build123d パーツを構築するメインクラス
load_ir, # JSON ファイルから IR を読み込む
validate_ir, # IR の構造を検証する(不正なら ValueError)
render_part, # パーツを 4 ビュー PNG に描画
render_step, # STEP ファイルを読み込んで 4 ビュー PNG に描画
get_anchor_position, # ソリッドのアンカー座標を取得
apply_transform, # 回転・平行移動を適用
)
| 名前 | シグネチャ | 説明 |
|---|---|---|
Build123dEmitter(ir) |
.build() -> Solid |
IR を検証・構築して build123d の Solid を返す |
render_part(part, png_path) |
-> Path |
パーツを 2x2 マルチビュー PNG に描画 |
render_step(step_path, png_path) |
-> Path |
STEP を読み込んで同様に描画 |
validate_ir(ir) |
-> None |
構造を検証(問題があれば ValueError) |
load_ir(path) |
-> dict |
JSON ファイルから IR を読む |
サンプル
リポジトリの examples/ に IR の書き方を示すサンプルがある。各サンプルは
STEP / STL / 4 ビュー PNG を workspace/<サンプル名>/ に書き出す(フォルダは自動作成)。
uv run python -m examples # 全サンプルを生成
uv run python -m examples.l_bracket # 個別に生成
| サンプル | 内容 | 使う機能 |
|---|---|---|
l_bracket |
L 字ブラケット(底板+垂直板+取り付け穴) | box, reference, linear 穴 |
flange |
円形フランジ(中央穴+ボルト円+面取り) | cylinder, circular 穴, chamfer |
enclosure |
角丸の中空ケース(上面開口+4 隅穴) | fillet, shell, grid 穴 |
hex_standoff |
六角スペーサ(貫通穴) | prism, hole |
o_ring |
O リング(ガスケット) | torus |
funnel |
漏斗(上下開口の円錐台) | cone(テーパ), shell |
ball_stud |
ボールスタッド(軸+先端球) | cylinder, sphere, reference offset |
angle_bracket |
補強リブ付き L 字ブラケット(曲げラウンド+ボルト穴+リブ) | extrude(L 断面+角丸), hole, transform |
semantic IR リファレンス
IR は features のリスト。各 feature は id(一意)と type を持ち、type ごとの
フィールドを足す。feature はリスト順に処理され、hole / fillet / chamfer / shell
は target に指定した既存 feature を変更する。
{
"features": [
{"id": "base", "type": "box", "size": [40, 30, 10]},
{"id": "post", "type": "cylinder", "radius": 5, "height": 20,
"reference": {"feature": "base", "anchor": "top_face_center"}},
{"id": "h1", "type": "hole", "target": "base", "diameter": 6, "depth": 10,
"reference": {"feature": "base", "anchor": "top_face_center"}}
]
}
feature.type
| type | 種別 | 必須フィールド | 任意フィールド |
|---|---|---|---|
box |
加算 | size:[x,y,z] |
|
cylinder |
加算 | radius, height |
|
sphere |
加算 | radius |
|
cone |
加算 | radius, height |
top_radius(既定 0 = 尖り) |
torus |
加算 | major_radius, minor_radius |
|
prism |
加算 | radius, sides, height |
正多角柱 |
extrude |
加算 | profile:[[x,y],...], height |
fillet_corners(断面の角丸) |
hole |
減算 | target, diameter, depth |
count, pattern |
fillet |
変更 | target, radius |
edges |
chamfer |
変更 | target, length |
edges |
shell |
変更 | target, thickness |
openings |
配置(加算プリミティブ共通)
| キー | 説明 |
|---|---|
reference |
{feature, anchor, offset?} — 既存 feature のアンカーを基準に配置 |
position |
[x, y, z] — 絶対座標に配置(reference が無い場合) |
transform |
{rotate:[rx,ry,rz], translate:[x,y,z]} — 回転・平行移動(度) |
anchor に使える値:
centertop_face_center/bottom_face_center/left_face_center/right_face_center/front_face_center/back_face_center- 角(8 種):
top_left_front/top_right_front/top_left_back/top_right_back/bottom_left_front/bottom_right_front/bottom_left_back/bottom_right_back
hole の複数穴
pattern を付けると複数の穴を一括で開ける(count は linear / circular で使用)。
| pattern.kind | 指定 | 説明 |
|---|---|---|
linear |
spacing:[dx,dy,dz] |
基準位置から等間隔に count 個 |
grid |
counts:[nx,ny], spacing:[dx,dy] |
+x / +y に nx × ny 個の格子 |
circular |
radius:R(任意で axis, start_angle, center) |
円周上に count 個(ボルト円) |
extrude の fillet_corners(断面の角丸)
押し出し前に 2D 断面の指定頂点をラウンドにする。L 字の内隅などに使う。
corners は profile の頂点インデックス(0 始まり、入力順)のリスト。
{"id": "body", "type": "extrude", "height": 40,
"profile": [[0,0],[50,0],[50,6],[6,6],[6,40],[0,40]],
"fillet_corners": {"corners": [3], "radius": 6}}
fillet / chamfer の edges
all(既定)/ vertical / horizontal / top / bottom
shell の openings
開口する面の名前リスト。例 ["top"]。省略すると全閉の中空になる。
使える面: top / bottom / left / right / front / back
例(円周ボルト穴+面取り)
{
"features": [
{"id": "flange", "type": "cylinder", "radius": 25, "height": 10},
{"id": "bolts", "type": "hole", "target": "flange", "diameter": 4, "depth": 10,
"reference": {"feature": "flange", "anchor": "top_face_center"},
"count": 8, "pattern": {"kind": "circular", "radius": 18}},
{"id": "edge", "type": "chamfer", "target": "flange", "length": 1, "edges": "top"}
]
}
MCP サーバ
AI エージェントが「IR を渡す → 4 ビュー画像が返る」ループで形状を反復設計できる。
cad-tools-mcp # インストール後のコンソールスクリプト
# または
python -m cad_tools.mcp_server # モジュールとして起動(stdio)
リポジトリ直下の .mcp.json により Claude Code では自動検出される。
| ツール | 入力 | 出力 |
|---|---|---|
validate_cad |
ir |
妥当性(valid / エラー文)。モデル構築なしの軽量チェック |
render_cad |
ir, save_dir? |
4 ビュー PNG 画像 + サマリ。save_dir 指定で STEP/STL/PNG も保存 |
export_cad |
ir, output_dir, basename? |
STEP/STL/PNG をディスクに保存しパスを返す |
render_cad は画像をインライン返却するため、エージェントが生成形状を直接「見て」
確認できる。構築に失敗した場合は例外ではなくエラー文を返すので、IR を自己修正しやすい。
開発
git clone https://github.com/ToPo-ToPo-ToPo/cad-tools
cd cad-tools
uv sync # 依存と本パッケージを editable install
uv run python test.py # 複合アセンブリ
uv run python test_ring.py # リング
uv run python test_schema_extensions.py # IR 拡張機能(全 12 ケース)
uv build # wheel / sdist を dist/ に生成
プロジェクト構成
cad_tools/ ライブラリ本体(配布パッケージ)
├── __init__.py 公開 API
├── emitter.py semantic IR → build123d ジオメトリ
├── validator.py IR の構造検証
├── references.py アンカー(面中心・角・中心)による相対配置
├── transforms.py 回転・平行移動
├── renderer.py VTK/PyVista による headless マルチビュー描画
├── generate.py ファイル入出力の CLI
└── mcp_server.py MCP サーバ(validate_cad / render_cad / export_cad)
examples/ サンプル(l_bracket / flange / ...)
experimental/ 退避した試作レンダラ(Blender / FreeCAD)
docs/images/ README 用の画像
レンダラについて
default は VTK / PyVista ベースの headless 実装(cad_tools/renderer.py)。
特徴エッジ抽出で CAD 風の輪郭を出し、STL 三角分割のノイズを除く。
過去に試した Blender / FreeCAD 版は headless 運用が不安定なため
experimental/ に退避している(経緯は experimental/README.md)。
ライセンス
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cad_tools-0.1.0.tar.gz.
File metadata
- Download URL: cad_tools-0.1.0.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
489b1bfd263c76a7d5375471bf397710d47fbe4cc95b2f502d178e43fe036383
|
|
| MD5 |
3fe564ab1e971291d91efe33900382c5
|
|
| BLAKE2b-256 |
7deca354708ff9940b9d46052ccbe97ebb321cb09f464e797cb8c01c3fc19b99
|
File details
Details for the file cad_tools-0.1.0-py3-none-any.whl.
File metadata
- Download URL: cad_tools-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
228545087bf62b6a0c193d97cb74e9d5832ade97f3688800893378a34487773b
|
|
| MD5 |
b8a4c96ee39948e22336d9ac9047c689
|
|
| BLAKE2b-256 |
9c9b5ca649854c6a30d2896853f26929962d3f3bb1016a321bdd336cf9d67e03
|