parametric-3d-printing について
CadQueryを使ってパラメトリックな3Dプリントモデルを作成し、STL形式で出力するスキルです。要件確認、寸法調査、段階的なプレビューとフィードバック、印刷時の推奨事項まで案内します。
主な機能
- 01CadQueryによるパラメトリックモデリング
- 02STL出力とプレビュー生成
- 03段階的な設計とフィードバック
- 04寸法調査とプリント適性の確認
活用シーン
- 01実測寸法に合わせた部品ケースの設計
- 02最終出力前のモデル反復
- 03FDMプリント用モデルの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ flowful-ai/ cad-skill --skill parametric-3d-printingインストール後、Claude Code で/parametric-3d-printingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdoutline_from_scan.pydesign-review.mdpreview.pyLICENSE.gitignoremesh_io.pygridfinity.pystl_to_3mf.pyrequirements.txtrun_cadquery_model.pyexamples/gridfinity_d110_bin.pymx_master3_bin_3x3.pytests/conftest.pytest_mesh_io.pytest_run_wrapper.pytest_stl_to_3mf.pytest_gridfinity.py詳細
CadQuery によるパラメトリック 3D プリント
概要
このスキルでは、CadQuery(Python)を使ってパラメトリックな 3D モデルを生成し、スライスに対応した STL ファイルとしてエクスポートします。CadQuery は pip でインストールでき、Python らしい API を備え、複雑な形状(フィレット、面取り、ブーリアン演算、アセンブリ)を他の選択肢より適切に扱えるため、優先して使用します。
セットアップ
# CadQuery requires Python 3.10-3.12 (OCC kernel lacks 3.13+ wheels)
python3.12 -m venv .venv && source .venv/bin/activate
# Install CadQuery and preview dependencies
pip install cadquery trimesh pyrender Pillow numpy lxml
CadQuery は内部で OpenCASCADE カーネルを使用します。trimesh、pyrender、Pillow、numpy はプレビュー・解析・反復のワークフローで使用されます。lxml は 3MF ライター(stl_to_3mf.py)に必要です。ディスプレイサーバーは不要で、すべて pyrender のオフスクリーンバックエンドを使ってヘッドレスでレンダリングされます。
CadQuery のインストールに失敗した場合(OCC カーネルのビルドエラー)、次をお試しください。
# Option 1: Use conda (CadQuery's officially recommended method)
conda install -c cadquery -c conda-forge cadquery
# Option 2: Use the pre-built wheels
pip install cadquery --find-links https://github.com/CadQuery/CadQuery/releases
実製品の寸法調査
実製品(スマートフォン、充電器、PCB、コネクターなど)と接続する物体を設計する場合は、ジオメトリのコードを書く前にウェブ検索で正確な寸法を調べてください。推測したり、おおよその値を使ったりしないでください。わずか 1~2 mm のずれでも、部品が使い物にならなくなることがあります。
調査する項目:
- コネクター/ポートの寸法(USB-C:開口部 8.4 x 2.6mm、Lightning、バレルジャック)
- デバイスの寸法(スマートフォンの幅/厚さ、PCB のフットプリント、充電器パックの直径)
- 取り付け穴のパターンとネジのサイズ(M2.5、M3 など)
- 標準部品の仕様(MagSafe パック:直径 56mm、厚さ 5.6mm)
- ケーブルの曲げ半径とストレインリリーフの要件
調査結果の使い方:
- 「[製品名] dimensions mm」または「[部品名] datasheet」で検索します
- 寸法精度が重要な場合は、少なくとも 2 つの情報源で照合します
- 調べた寸法を PARAMETERS セクションのコメントに記載します。
# MagSafe puck dimensions (source: Apple spec + iFixit teardown) puck_diameter = 56.0 # mm puck_thickness = 5.6 # mm - 判断に迷った場合は、外形寸法に 0.3~0.5mm のクリアランスを追加します
特に重要なのは、スマートフォンケース/スタンド、充電器マウント、PCB エンクロージャー、ケーブル管理、アダプター用フィッティング、既存製品にクリップ留めしたり巻き付けたりするものです。
基本的なワークフロー
- 要件を収集する(下記の「要件の収集」を参照)
- 実製品が関係する場合は寸法を調査する(上記を参照)
- フェーズ 1、基本形状:外殻を作成し、プレビューして、ユーザーのフィードバックを得ます
- フェーズ 2、機能:機能的な詳細を追加し、プレビューして、ユーザーのフィードバックを得ます
- フェーズ 3、最終納品:フィレット、クリーンアップ、最終プレビュー+STL+プリントに関する推奨事項
- 納品後にパラメーターの調整を提案します
これはユーザーと協力し、進捗を見せながら進めるプロセスです。完成モデルを持って戻るまで、ユーザーに何も見せずに作業を進めないでください。各フェーズで進捗を示し、次の段階に進む前にユーザーのフィードバックを反映してください。
要件のヒアリング
コードを書く前に、次の項目について会話形式でユーザーと確認してください。質問を一度にすべて並べるのではなく、まず最も重要な質問をして、その回答に応じて追加の質問をしてください。指定がない場合は、妥当なデフォルト値を使用してください。
これは何ですか? 物体の種類、目的、何を収納・保護するのか、または何に取り付けるのかを確認します。ほかのことに進む前に、物体の全体像を明確に把握してください。
重要な寸法 PCB のサイズ、スマートフォンの幅、ネジの間隔、巻き付ける対象の直径など、必ず適合させる必要のある寸法です。これらは変更できず、ほかのすべての設計を左右します。
取り付け方法 どのようにほかの物体と接続しますか?ネジ(サイズは?)、スナップフィット、粘着テープ、磁石、机の上に置く自立式などがあります。壁の厚さ、ボスの配置、全体構造に影響します。
プリンターと材料 どのプリンターを使っていますか?(Bambu、Prusa、Ender など)ノズルサイズは?材料は何ですか?(PLA、PETG、TPU)これらは公差、最小フィーチャーサイズ、設計上の制約に直接影響します。デフォルト値は、ノズル 0.4mm、PLA、レイヤー高さ 0.2mm です。
機能上の要件 通気性・気流、防水性、ケーブルの配線、アクセスパネル、覗き窓、積み重ね、重量制限などです。対象物に関連する項目だけを質問してください。
外観の好み 角を丸くするか鋭くするか、ミニマルな外観にするか工業的な外観にするか、色の希望(レイヤーラインの見えやすさに影響します)などです。簡潔に尋ねてください。多くのユーザーは、外観よりも機能を重視します。
まず最初の 2 項目(何を作るのか、寸法)から始め、必要に応じて取り付け方法と材料について質問してください。外観については、ユーザーがこだわりを示した場合や、構造上の選択に影響する場合にのみ質問してください。
段階的なプレビューのワークフロー
モデルは段階ごとに作成します。各段階で STL をエクスポートし、プレビューをレンダリングして、自分で確認した後、次に進む前にユーザーに見せてフィードバックを求めてください。これにより、問題を早期に発見し、ユーザーにも作業に参加してもらえます。
プレビューの手順(各段階で使用)
一括実行(スクリプトを実行し、レンダリングして、結果を JSON として解析):
python3 run_cadquery_model.py model.py --preview --strict
model.py を実行し、出力された STL を見つけて、多視点のプレビューをレンダリングし、success、stdout、stderr、stl、preview、watertight を含む JSON 結果を出力します。--strict を指定すると、メッシュが水密でない場合はエラーになります。これをデフォルトの反復処理として使用します。success が false の場合は、stderr フィールドを確認して CadQuery スクリプトを修正し、再実行してください。
レンダリングのみ(STL がすでにある場合):
python3 preview.py model.stl preview.png --views multi
次にプレビュー画像を確認し、design-review.md のチェックリストに照らして自分でレビューします。ユーザーに見せる前に、気付いた問題を修正してください。
フェーズ 1:基本形状
基本となる外形を作成します。全体寸法、シェル・壁、底板を含みます。まだ切り欠き、フィレット、細部は追加しません。
- パラメーターと基本形状を使ってスクリプトを作成します
- STL をエクスポートし、プレビューをレンダリングします
- 自分で確認します:形状とサイズは適切に見えますか?底面は印刷に適した平面ですか?
- プレビューをユーザーに見せます:「基本形状はこのようになっています。詳細を追加する前に、この形で問題ないでしょうか?」主な寸法も含めます。
- フィードバックを待ちます。ユーザーが変更を希望する場合は、次に進む前にこの段階で調整します。
フェーズ 2:機能の追加
穴、切り欠き、取り付けボス、ケーブルスロット、通気口、スナップフィット、内部構造など、機能上の詳細を追加します。
- スクリプトに機能を追加します
- STL をエクスポートし、プレビューをレンダリングします
- 自分で確認します:すべての機能が見えていますか?ブーリアン演算の結果はきれいですか?穴の位置は適切ですか?
- プレビューをユーザーに見せます:「[機能の一覧]を追加しました。最終化する前に変更したい点はありますか?」
- フィードバックを待ちます。必要に応じて調整します。
フェーズ 3:最終納品
仕上げとして、フィレット、面取り、エッジのクリーンアップを行います。プリント可能性を全体的に確認します。
- フィレット/面取りを追加します(半径が大きいものから順に、シェル処理の後に適用します)
- 最終 STL をエクスポートし、プレビューをレンダリングします
design-review.mdの完全なチェックリストを使って全項目を自己レビューします。目視検査、寸法確認、プリント可能性の分析を行います- 見つかった問題を修正し、必要に応じて再エクスポートします
- ユーザーに納品します:最終 STL +プレビュー画像+プリント推奨事項(向き、サポート、インフィル、材料に関する注意事項)
重要: モデルが非常にシンプルな場合(例:穴が 2 つある平らなブラケット)を除き、フェーズを省略したり、まとめたりしないでください。密閉形状、複数のフィーチャー、または厳しい公差がある場合は、必ず 3 つのフェーズすべてに従ってください。
目視検査の完全なチェックリスト、寸法確認コード、プリント可能性分析用のヘルパーについては、design-review.md を参照してください。
プリント推奨事項(最終納品)
最終 STL を納品する際は、必ず 1 行のスライサー設定例と簡単な理由を添えてください。Bambu Studio、PrusaSlicer、OrcaSlicer は、フィラメントとプロセスのプリセットに基づいて適切なデフォルト設定をすでに適用するため、スライサーの設定をすべて書き直さないでください。このモデルで重要な項目に限って伝えてください。材料、レイヤー高さ、壁の数、インフィル、サポート、向きを指定します。モデルに必要な場合にのみ、以下の基準から調整してください。
基準となる設定例(0.4mm ノズル、一般的な FDM):
PLA、レイヤー高さ 0.2mm、壁 2 枚、ジャイロイドインフィル 15%、サポートなし、向き:平らな面をベッドに置く。
基準から変更する場合:
- 荷重を受けるブラケット/フック/ヒンジ:インフィルを 25~40%、壁を 3~4 枚に増やし、強度を高めるため PLA より PETG を検討します。
- 薄い装飾用の壁や花瓶:インフィル 0%、花瓶モードまたは壁 1 枚にします。
- 背が高く細いパーツ:ベッドへの定着性を高めるため、ブリムを追加します。
- 柔軟なパーツ(ガスケット、グリップ):TPU 95A、レイヤー高さ 0.2mm、低速、サポートなしにします。
- 形状上避けられない実用的なオーバーハング:ツリーサポートを使うか、ユーザーに分かるよう明記します。
- 屋外/高温環境:PLA ではなく PETG または ASA を使います。
- 食品/肌に触れる用途:FDM パーツは食品安全性が保証されないことを明記し、食品安全性のあるコーティングを推奨します。
納品時の形式:
Print settings: PLA, 0.2mm layer, 2 walls, 15% gyroid infill, no supports.
Orientation: place flat back side on the bed (front face up).
Why: the case has no overhangs above 45°, and 15% infill is plenty for a
TPU-adjacent protective shell.
約 3 行にまとめてください。スライサー設定をすべて列挙しないでください。スライサー側で設定を把握しています。
スクリプトテンプレート
スクリプトは必ず次のように構成します。
import cadquery as cq
# ============================================================
# PARAMETERS - Edit these to customize the model
# ============================================================
# Overall dimensions
width = 60.0 # mm - outer width
depth = 40.0 # mm - outer depth
height = 25.0 # mm - outer height
# Wall and structural
wall = 2.0 # mm - wall thickness (min 1.2 for FDM)
corner_r = 2.0 # mm - corner fillet radius
# Tolerances
fit_clearance = 0.3 # mm - clearance for press-fit (adjust per printer)
# ============================================================
# MODEL
# ============================================================
result = (
cq.Workplane("XY")
.box(width, depth, height, centered=(True, True, False))
# ... build geometry using parameters above (bottom at Z=0)
)
# ============================================================
# EXPORT
# ============================================================
# Use tolerance=0.01, angularTolerance=0.1 for consistent tessellation
# across models. Defaults give coarser, wildly variable STL sizes.
cq.exporters.export(result, "output.stl",
tolerance=0.01, angularTolerance=0.1)
print(f"Exported: {width}x{depth}x{height}mm")
主なルール
パラメーターを最初に定義する
- 寸法はすべて先頭の PARAMETERS セクションに記述します
- 説明的な名前を使います:
d1ではなくscrew_hole_d - コメントに単位(常に mm)を付けます
- 関連するパラメーターは、空行とセクションコメントでグループ分けします
プリントしやすいデフォルト設定
FDM 設計の主なデフォルト設定:
| プロパティ | 最小値 | 推奨値 |
|---|---|---|
| 壁厚 | 1.2mm | 2.0mm |
| レイヤー高さ | 0.08mm | 0.2mm |
| 穴のクリアランス | 0.2mm | 0.3mm |
| 圧入のしろ | 0.1mm | 0.15mm |
| 最小フィーチャーサイズ | 0.4mm(ノズル径) | 0.8mm |
| フィレット半径(底面) | 0.5mm | 1.0mm |
| ブリッジスパン | - | サポートなしで < 20mm |
| オーバーハング角度 | - | 垂直から < 45 度 |
材料ごとの調整: TPU は柔軟性があるため、より大きなクリアランス(約 0.5mm)が必要です。PETG は粘着性が高いため、はめあいのクリアランスに +0.1mm を加えます。ABS は約 0.5~0.7% 収縮するため、重要な寸法を少し大きめにします。迷った場合は、まず小さなテストパーツをプリントしてください。
向きを考慮する
- プリント時の向きを考慮して設計します
- 平らな底面が最もプリントしやすいです
- オーバーハングを避ける設計にし、可能な限りサポートを使わないようにします
- フィレットにはサポートが必要なため、底面のエッジにはフィレットではなく面取りを追加します
- スクリプト内に想定するプリントの向きをコメントで記載します
CadQuery のパターン
知っておくべき一般的なパターン:
中空の筐体(ブーリアン減算、推奨):
outer = (
cq.Workplane("XY")
.box(width, depth, height, centered=(True, True, False))
.edges("|Z").fillet(corner_r)
)
inner = (
cq.Workplane("XY")
.workplane(offset=floor_t)
.box(width - 2*wall, depth - 2*wall, height, centered=(True, True, False))
.edges("|Z").fillet(max(0.1, corner_r - wall))
)
result = outer.cut(inner)
ねじ用ボス:
.pushPoints([(x, y)])
.circle(boss_od / 2).extrude(boss_h)
.pushPoints([(x, y)])
.hole(screw_d + fit_clearance)
スナップフィットクリップ:
# Cantilever beam with overhang hook
.workplane(offset=wall)
.moveTo(x, y).rect(clip_w, clip_l).extrude(clip_h)
# Add hook at tip with a small overhang (< 45 deg)
通気グリッド:
.pushPoints(vent_positions)
.slot2D(slot_l, slot_w).cutThruAll()
その他のパターン:取り付けブラケット、ケーブル配線用チャンネル、テキスト/ラベル(.text())、位置合わせピンを使った複数パーツのアセンブリ。
よくある落とし穴
- 中空化:
.shell()よりブーリアン減算を優先します。.shell()は脆弱です。テーパーのあるボディ、ロフト形状、複数のプリミティブの結合、多数のフィレットがある形状では失敗します。信頼性の高い方法は次のとおりです。outer = cq.Workplane("XY").box(w, d, h, centered=(True, True, False)).edges("|Z").fillet(corner_r) inner = ( cq.Workplane("XY") .workplane(offset=floor_t) .box(w - 2*wall, d - 2*wall, h, centered=(True, True, False)) .edges("|Z").fillet(max(0.1, corner_r - wall)) ) result = outer.cut(inner).shell()を使うのは、ボディが単一のシンプルなプリミティブ(.box()または.cylinder()が 1 つ)で、すべての面の肉厚が均一な場合に限ります。迷った場合は、ブーリアン減算を使ってください。 - 作成順序:カットしてからフィレットではなく、フィレットしてからカットします。ジオメトリがまだきれいなプリミティブのうちにフィレットを適用してください。ボディに穴、スロット、ポケットをカットした後は、できたエッジへのフィレットが失敗したり、不適切なジオメトリになったりすることがよくあります。面取りにも同じルールが当てはまります。
- フィレットの失敗:フィレットは半径の大きいものから小さいものへ適用してください。フィレットを
try/exceptで囲み、半径を暗黙に小さくすることは避けてください。 フィレットの失敗は、ジオメトリまたは半径が不適切であることを意味します。根本原因(半径が大きすぎる、肉厚が半径より薄い、フィレットによって退化する隣接面など)を見つけて修正してください。 - 厚さゼロのジオメトリ:ブーリアン演算によって無限に薄い壁ができないようにしてください。表面をちょうど貫通させるボディをカットする際は、小さなイプシロン(0.01mm)を加えてください。
- 座標系:CadQuery はデフォルトでジオメトリを原点に配置します。
.box()でcentered=(True, True, False)を指定し、底面を Z=0 に配置すると、.faces("<Z")が常にプリントベッドになります。 - 穴の方向:
.hole()はデフォルトでパーツ全体を貫通してカットします。座ぐりには.cboreHole()、皿穴には.cskHole()を使ってください。 - テーパーの方向:
.extrude(taper=angle)では、テーパー角が正の場合は形状が狭まり(内側にドラフト)、負の場合は外側に広がります。これは多くの人が予想する方向とは逆です。 - ロフトは脆弱です:
.loft()は多くの断面の組み合わせで失敗します。形状とその相似形の間をつなぐ場合は、.extrude(taper=angle)を優先してください。.loft()は、実際に異なるプロファイル間(例:円から長方形)をつなぐ必要がある場合にのみ使ってください。 - エクスポートエラー/非ウォータータイトな STL:エクスポートに失敗したり、プレビューで非ウォータータイトなメッシュと報告されたりした場合、ジオメトリは無効です(通常は自己交差するブーリアンや厚さゼロの面が原因です)。原因を修正し、問題を覆い隠さないでください。
python3 preview.py model.stl --strictを実行すると、ウォータータイトでない出力で明示的に失敗します。
エクスポート
# STL (for slicing) - always set tolerance + angularTolerance for
# consistent tessellation. Defaults produce variable file sizes and
# over-tessellated glyphs on text features.
cq.exporters.export(result, "model.stl",
tolerance=0.01, angularTolerance=0.1)
# STEP (for further CAD editing)
cq.exporters.export(result, "model.step")
印刷用には必ず STL をエクスポートしてください。ユーザーが Fusion 360 などで編集する可能性がある場合は、STEP も任意でエクスポートしてください。
複数パーツのモデル
複数のパーツ(例:筐体+蓋)があるモデルの場合:
# Export each part separately
cq.exporters.export(body, "enclosure_body.stl")
cq.exporters.export(lid, "enclosure_lid.stl")
どのパーツかユーザーが分かるよう、ファイルには内容を説明する名前を付けてください。
Gridfinity ビン
Gridfinity に関するリクエスト(42mm モジュラーグリッドシステム用のビン、インサート、クレードル)では、バンドルされている gridfinity.py モジュールを使用してください。ベースプロファイルを独自に実装しないでください。このモジュールはテスト済みで、仕様に準拠しており(ベースプロファイル、スタッキングリップ、6x2mm のマグネット穴、26mm 四方の M3 ネジ穴)、実用的なエラーメッセージでパラメーターを検証します。
ワークフロー:
- このスキルのディレクトリから
gridfinity.pyをモデルスクリプトと同じ場所にコピーします(ベンダー化されたモジュールです。生成されるスクリプトは単独で実行できる状態にしてください)。 GridfinityBinAPI を使って作成します。
import cadquery as cq
from gridfinity import GridfinityBin
bin = GridfinityBin(grid_x=3, grid_y=2, height_units=3,
stacking_lip=True, magnets=False)
bin.add_pocket(length=88.6, width=72.6, corner_r=(12.0, 1.0)) # cradle
# or: bin.add_compartments(cols=3, rows=2, scoop_r=6, label_tab=True)
# or: bin.add_polygon_pocket(points, depth=15, clearance=0.3)
# or: bin.add_cylinder_pocket(diameter=22, center=(42, 27), # finger well; overlapping pockets merge
# tilt=35, tilt_dir=(-1, 0), round_bottom=True) # smooth angled thumb scoop
# or: bin.add_finger_notch(side="+Y", width=20, offset=40) # offset slides it along the wall
result = bin.build()
cq.exporters.export(result, "my_bin.stl", tolerance=0.01, angularTolerance=0.1)
print(bin.summary())
要点:
- 仕様定数:グリッドピッチは 42mm、高さ単位は 7mm です。派生値(設置面積、リップの高さ、床面の Z 座標、使用可能な空洞の深さ)はすべてビルダーで参照できます。
bin.outer_w、bin.outer_d、bin.total_h、bin.floor_z、bin.max_depthを確認してください。bin.summary()を呼び出すと、これらがすべて表示されます。再計算せず、これらの値を参照してください。 - オブジェクト用ポケットのサイズ:片側あたり 0.3mm の嵌合クリアランスを加え、オブジェクトを簡単に出し入れする必要がある場合は、さらに片側あたり約 1mm 加えます。
- 実物の形状に合わせたポケット:
outline_from_scan.pyは、オブジェクトの STL スキャンから最大断面の輪郭を抽出します(位置合わせ、仕様寸法へのスケーリング、スライス、結合)。add_polygon_pocketですぐに使用できます。 - 高さの選択:中身を保持できる高さにします。中身が縁より上に突き出してもかまいません(
examples/gridfinity_d110_bin.pyを参照)。 magnets=Trueにするには、マグネット式ベースプレートが必要です。引き出し用ビンでは無効にしてください。
ポケットが大きすぎる、壁が薄すぎる、またはネジ用の床が浅すぎる場合、ビルダーは具体的なメッセージを含む GridfinityError を発生させます(いくつかのチェックは add_* 呼び出し時に、残りは build() 内で実行されます)。パラメーターを修正し、検証を回避しないでください。
ユーザーがモジュールで対応していないもの(ベースプレートや特殊なリップなど)を求めた場合は、カスタム形状を使用しますが、仕様定数の参照元には gridfinity.py を使用してください。リリースを提供する際は、モデルスクリプトと一緒に gridfinity.py も同梱してください。
パラメーター調整の提案
最終モデルを提供した後は、必ず主要なパラメーターを要約表にまとめ、調整の希望があるか尋ねてください。これにより、設計全体を説明し直さなくてもユーザーが微調整できます。
例:
Here's your final model! Current parameters:
| Parameter | Value |
|----------------|--------|
| Width | 90 mm |
| Depth | 65 mm |
| Height | 30 mm |
| Wall thickness | 4 mm |
| Cable slot | 18 mm |
| Corner radius | 3 mm |
| Fit clearance | 0.3 mm |
Want me to adjust anything? Just say e.g. "make it 5mm taller" or "wider cable slot."
ユーザーが変更したいと思われるパラメーターだけを含めてください。eps や nozzle_d などの内部定数は省略します。寸法、構造、許容差の順に論理的にまとめてください。
出力チェックリスト
モデルを提供する前に、以下を確認してください。
- すべての寸法がパラメーター化されている(形状コードにマジックナンバーがない)
- 壁の厚さが 1.2mm 以上である
- プリントしやすい設計になっている(オーバーハングとサポートが最小限)
- コメントにプリント方向が記載されている
- STL がエクスポートされ、ファイルサイズが妥当である(0 バイトではない)
- 単位付きのわかりやすいパラメーター名が使われている
- スクリプトがエラーなく実行できる
- 複数視点のプレビューが生成され、目視で確認されている
- プレビューで形状、特徴、プロポーションが正しいことを確認できる
- バウンディングボックスの寸法が要件に一致している
- STL とプレビュー PNG の両方をユーザーに提供する