mcpField
D
dxf

dxf

github.com/earthtojakeデザイン・UI23.9k9.4k 回インストール今日更新
リポジトリ

dxf について

要件や CAD ジオメトリをもとに 2D DXF 図面を作成、検証するスキルです。CAD や製造のワークフロー向けで、build123d ジオメトリを使い、図面の新規作成や STEP 部品からの展開図生成に対応します。

主な機能

  1. 012D ジオメトリから DXF 図面を作成
  2. 02CAD 部品から展開図を生成
  3. 03ジオメトリを名前付きレイヤーに分類
  4. 04図面ジオメトリと出力を検証
  5. 05DXF スナップショットを描画

活用シーン

  1. 01レーザーやウォータージェット切断用輪郭の準備
  2. 02STEP 部品から展開図を作成
  3. 03テンプレート、パネル、ガスケットの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/earthtojake/text-to-cad --skill dxf

インストール後、Claude Code で/dxfを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
agents/
openai.yaml
references/
generator-templates.md

詳細

DXF の生成と検証

出典:earthtojake/text-to-cadで保守されています。 実行時の信頼できる情報源として、インストール済みのローカルスキルファイルを使用してください。 リポジトリのリンクは、出典とリリース確認のためだけのものです。

セットアップ

uv 経由で cadgen を実行してください。これにより、このスキルのコマンドは、CAD アプリのサーバーと同じインストール環境およびウォームビルドデーモンを共有します。

  • 以下の cadgen は uvx --no-config --managed-python --python 3.13 --from cadgen==0.7.26 cadgen を意味します。
  • 以下の python は uvx --no-config --managed-python --python 3.13 --from cadgen==0.7.26 python を意味します。

初回実行時にこのインストール環境がダウンロードされ、最初のスナップショット作成時にヘッドレスブラウザーがダウンロードされます。以降の実行では、どちらも再利用されます。

cadgen doctor <skill-dir> は、使用中のインストール環境を報告し、それがこのスキルで固定されているものと一致すること、および CAD カーネルが読み込まれることを確認します。インストールエラーやカーネルの読み込みエラーが発生した場合に使用してください。

図面は build123d のジオメトリであるため、図面のビルドでは STEP のビルドと同様に CAD カーネルが読み込まれます(初回は約 2.5 秒。再実行時はウォームデーモンがこの処理を吸収します)。 cadgen dxf snapshot に Node は不要です。cadgen に同梱の ezdxf で図面を平面化し、バンドルされたヘッドレスブラウザーで描画します。

目的

自然言語の要件または CAD ジオメトリから 2D DXF 図面を作成・変更し、検証済みの図面成果物を生成して、確認済みの出力を返します。DXF 図面の信頼できる情報源は、パラメーターを持たない @dxf モデル関数を 1 つ定義した <name>.py という名前の Python ファイルです。

図面はモデルです。 @step パーツと同じラッパー、レコード、鮮度ゲート、ビルドジョブを備えます。出力は .dxf ファイル 1 つで、ジオメトリツリーはありません(図面にリンクするものはありません)。実行のたびに、隣接する <name>.dxf(またはデコレーターで指定した out=)が書き込まれます。ソースに変更がなければ何も行いません。パーツモデル(本体内の bracket() など)を呼び出す図面は、そのパーツの GEOMETRY が変更されると古くなり、変更されなければ最新の状態です。cadgen store why <drawing>.py で判定理由を確認でき、--force で強制的に再ビルドできます。CAD Viewer と dxf snapshot は .dxf ファイルそのものを読み込むため、切断サービスに渡すファイル、ビューアーが描画するファイル、スナップショットがレンダリングするファイルは、すべて同一です。

契約

@dxf 関数はパラメーターを受け取らず、build123d の 2D ジオメトリを返します。DXF の書き込みはエンジンが行います。 ドキュメントの作成、ファイル名の指定、エンティティの配置は不要です。@step と同じ役割分担です。

from cadgen import build123d as bd
from cadgen import dxf


HOLE_D = 4.5


@dxf
def gasket():
    with bd.BuildSketch() as cut:
        bd.Rectangle(60, 40)
        bd.Circle(HOLE_D / 2, mode=bd.Mode.SUBTRACT)
    return cut.sketch          # bare shape -> the CUT layer


if __name__ == "__main__":
    gasket()
  • 単一のシェイプ → CUT レイヤー 1 つ。ほとんどの図面では、これが契約のすべてです。
  • {layer: shape} → 図面に複数の CAM 操作(CUT/ENGRAVE/SCORE)が実際に必要な場合は、名前付きレイヤーを使います。すべての子にラベルが付いた Compound も同じ意味です。
  • パラメーターなし。 寸法はモジュール定数(HOLE_D = 4.5)または図面の派生元であるパーツからインポートした定数にします。図面を変える場合は、別のファイルにします。
  • テキストには、マーキングレイヤー上に彫刻用のアウトラインとして bd.Text(...) を使用します。DXF の TEXT エンティティは使用しません。切断およびマーキングのツールチェーンではジオメトリを使用し、CAM 内でのフォント描画は信頼性に欠けるためです。
  • ジオメトリは XY 平面上になければなりません。 ソリッドから取得した面は、そのソリッドの高さにあります。面を移動してください(flatten.flatten_face(face) または bd.Location((0, 0, -z)) * face)。エンジンは、XY 上の投影を黙って書き出すのではなく、平面外のジオメトリを拒否します。
  • 出力バイト列はジオメトリから決まります。 レイヤーは名前順に、エンティティは幾何学的な内容順に並べ替えられるため、同じ図面を再ビルドすると、初回かウォーム実行かを問わず、どのマシンでも同一のファイルになります。

3 つの DXF ワークフロー

新しい図面を作成する際は、該当するワークフローのテンプレート全体を references/generator-templates.md からコピーしてください。

  1. ゼロから作図する場合(元となる 3D モデルのないガスケット、パネル、テンプレート、切断レイアウト):スケッチを作成して返す <name>.py。

  2. 生成した STEP パーツのフラットパターン:派生元のモデルと同じ場所に置き、独自のファイル名のベース部分を持つ図面スクリプト(1 ファイルにつき 1 モデル — bracket.py の隣に bracket_drawing.py)。モデルをインポートして呼び出します。これは、アセンブリが子モデルを組み込む方法とまったく同じです。インポートではビルドは行われず、図面の build 内で呼び出すとパーツのジオメトリが返されます(古くなっている場合は、先にパーツをビルドします)。

    from cadgen import dxf, flatten
    from bracket import bracket        # a child: tracked by its RESULT
    
    KERF = 0.15
    
    
    @dxf
    def bracket_drawing():
        return flatten.flat_pattern(bracket(), coordinate=3.0, kerf=KERF)
    
    
    if __name__ == "__main__":
        bracket_drawing()
    

    図面のレコードはパーツのツリーを固定するため、ジオメトリが変わるパーツの編集によって図面は古くなりますが、変わらない編集(コメント、リファクタリング、色の変更など)では最新の状態が保たれます。パーツからインポートした定数(from bracket import THICKNESS)も、同じ方法で値によって追跡されます。

  3. インポートした STEP のフラットパターン(Python ソースのない .step/.stp):cadgen.read_step で読み込みます(ストアからウォーム状態で読み込まれ、ジオメトリは build123d.import_step と同じです)。ビルドで読み込むファイルはすべて入力として扱われます。ベンダー提供の STEP を置き換えると、--force を指定しなくても図面自体が古くなります。

    from pathlib import Path
    
    from cadgen import dxf, flatten, read_step
    
    _HERE = Path(__file__).resolve().parent
    
    KERF = 0.15
    
    
    @dxf
    def panel_flat():
        panel = read_step(_HERE / "imported" / "vendor_panel.step")   # recorded input
        return flatten.flat_pattern(panel, coordinate=3.0, kerf=KERF)
    
    
    if __name__ == "__main__":
        panel_flat()
    

    このプロジェクトが生成する STEP は絶対に読み込まないでください。 @step モデルが書き出す .step を読み込んでもループにはなりませんが、モデルを実行するたびに入力が変わる図面になります。そのため鮮度チェックで「最新」と判定されることはなく、ビルドのたびに全面的に再ビルドされ、フラットパターンは最後の実行でディスクに残された内容に依存します。ソース STEP は図面と同じ場所にある imported/ ディレクトリに置き、ほかの入力と同様にコミットしてください。入力パスと出力パスを別のファイルにすることが、ルールのすべてです。このプロジェクトが生成する STEP には、代わりにワークフロー 2 を使ってください。モデルスクリプトをインポートして呼び出せば、結果によって追跡され、アーティファクトには一切触れません。

1 ファイルにつき 1 モデルにすることを推奨します。図面には専用のスクリプトを用意してください。1 ファイルで複数のモデルを宣言することもできます(2 つの @dxf 図面、または @step と並ぶ @dxf など)。それぞれが独自のレコード、出力、ジョブになります(モデルが 1 つなら <file>.dxf、同じファイルに複数のモデルがある場合は <function>.dxf を書き出します)。ただし、ファイルのクロージャーは共有されるため、1 つを編集するとすべてが再ビルドされます。図面はモデルを組み込みますが、その逆はありません。@step の本体から @dxf 関数を呼び出しても、2D ジオメトリが得られるだけで、何もリンクされません。ビューアーのカタログに表示されるのはアーティファクトだけです。スクリプトは一覧表示されず、実行で書き出された .dxf がビューアーに表示される項目になります。

このスキルを使う場面

ユーザーから、レーザー、プラズマ、ウォータージェット、CNC ルーティング用の DXF ファイル、2D 図面、プロファイル、輪郭、テンプレート、ガスケット、パネル、フラットパターン、切断レイアウトを求められた場合に、このスキルを使ってください。

DXF の派生元となる 3D パーツまたはアセンブリには $cad を使ってください。SendCutSend 固有のアップロード前チェックには $sendcutsend を使ってください。

デフォルト

ユーザーから別の指定がない限り、以下のデフォルトを使用してください。

  • 単位:ミリメートル。単位はエンジンが設定するため、図面では宣言しません。
  • ジオメトリは XY 平面上に 1:1 の縮尺で配置します。
  • 切断プロファイルは閉じます。開いた輪郭は、曲げ/彫刻/参照レイヤーに配置します — 生成時の検証でこれが強制されます(「検証」を参照)。
  • CAD を基にした部品では、輪郭を描き直すのではなく、実際のトポロジーから cadgen.flatten で導出します。planar_faces は面を選択し、 flatten_face は面を正確に XY 平面へ展開し、union_faces は面を結合し、 flat_pattern はこれらすべてを 1 回の呼び出しで行います。信頼できる 3D トポロジーが ない場合に限り、パラメトリックな輪郭を手描きします。
  • カーフ/工具半径の補正には、flatten.offset_profile(shape, amount) または flat_pattern(..., kerf=...) を使用します。座標を手作業でオフセットしないでください。
  • 曲線は曲線のままにします。 結合とオフセットは正確な OCC 演算のため、フィレットされた角は ARC として、穴はカーフ補正後も CIRCLE としてエクスポートされます。プロファイルが 数百個の短い LINE として出力される場合は、サンプリングされたパスにフォールバックしています — そのまま受け入れず、原因を調べてください。
  • レイヤーで意図を表します。切断ジオメトリと曲げ/折り線は別々のレイヤーに配置し、 下流ツールが切断ではなく曲げとして分類できるよう、曲げレイヤー名には「bend」を含めます。
  • DXF レイヤーは図面の構造であり、STEP の部品/アセンブリ構造ではありません。

ツール

python <drawing>.py [flags]                    # its __main__ calls the @dxf model, which writes the .dxf
cadgen dxf snapshot <drawing.dxf> <file.png>   # render it
cadgen store why <drawing>.py                  # why the drawing is stale or current

スクリプトの実行(__main__ 呼び出し)が唯一の入口です。 cadgen dxf build はありません。.dxf にはコマンドで実体化する必要がある派生状態がありません — ファイル自体が成果物であり、CAD Viewer と dxf snapshot はどちらもファイルのバイト列から直接描画します。図面のゲートにより再ビルドは低コストです。ソースに変更がなく、.dxf の検証が通り、部品の子要素にも変更がなければ何も行わず、--force を指定すると再ビルドします。バイト列は図面のジオメトリに基づいて生成されるため、コールド実行でもウォーム状態のデーモンワーカーでも同じファイルが書き込まれます。ビルド同士が互いを待ったりキャンセルしたりすることはありません。部品を呼び出す図面は、他の親と同様に部品を並列でビルドします。

インポート済みの .dxf には何も必要ありません — そのままスナップショットまたは Viewer に渡してください。

アクティブなプロジェクトの Python インタープリターを使用します。python はインタープリターのプレースホルダーとして扱い、インターフェース全体を確認するには --help を使用してください。ターゲットパスはコマンドの現在の作業ディレクトリを基準に解決されます。成果物を所有するワークスペースから、cwd 相対のターゲットパスを指定して実行してください。図面スクリプトは、派生元のジオメトリと同じディレクトリに <name>.py という名前で配置します。

フラグ(モデルスクリプト自体が実行されます。生成 CLI はありません):

  • --force — 記録済みの出力が最新の場合でも再生成します。
  • --verbose、--json。

実行結果は STEP モデルと同様、標準出力に built DXF/plate_drawing.dxf または current DXF/plate_drawing.dxf をそのまま出力し、進行状況は標準エラーに出力します。--json を指定すると、結果は 1 行の JSON(outcome、document、tree を含み、図面の場合 tree は null)となり、進行状況は遷移ごとに 1 行の JSON になります。

1 スクリプトにつき 1 図面です。ビルドするスクリプトをそれぞれ実行してください。@dxf 関数の戻り値に出力パスを含めないでください。図面の出力先を指定できるのは、デコレーターの out= のみです(スクリプトからの相対パス)。

cadgen dxf snapshot は図面を平面図として PNG 静止画に描画します — CAD Viewer が表示するものと同じ画像を、同じ平坦化処理と同じ描画コードで出力します。

cadgen dxf snapshot path/to/imported.dxf review.png
cadgen dxf snapshot path/to/drawing.dxf review.png --appearance dark

.dxf ドキュメントのみを受け付けます — モデルスクリプトは名前で拒否されます(python <drawing>.py を実行してから、書き出された図面のスナップショットを作成してください)。図面全体を画像に収まるよう調整し、正面から、ファイルで宣言されたペンを使って描画します。独自のペンを持たないエンティティ(ACI 7)は、アピアランスの背景に対して前景色で表示されます。このコマンドは ezdxf で図面を平坦化し、共有スナップショット CLI(cadgen.snapshot_cli)と、すべてのレンダリングスキルで使用される同じヘッドレスブラウザーランタイムを通じてレンダリングします。 OUT — 第 2 の位置引数 — は指定どおりに書き込まれます。相対パスは現在の作業ディレクトリを基準に解決されます。レンダリングの開始前に出力先が削除され、完成した画像はアトミックに書き込まれます。そのため、反復中は同じ名前を再利用してください(読み取る画像が直前に実行したレンダリングのものだと確実に確認できます)。2 つを本当に比較する必要がある場合は、反復ごとに名前を付けてください。不正なリクエストの組み合わせは、OUT に触れる前にエラーになります。リクエストが受け付けられた後は、まず OUT がクリアされるため、それ以降にエラーが発生すると、古い画像ではなくファイルが存在しない状態になります。ディレクトリ(OUT としての tmp/)は例外的なケースで、その中にタイムスタンプ付きの名前が自動生成され、saved snapshot: 行に表示されます。

構文:cadgen dxf snapshot TARGET [OUT] [flags]。フラグ:--appearance light|dark、--size-profile、--width/--height、--job、--debug、 --json。図面には 3D シーンの設定がないため、--camera、--display、 --mode、--view-labels は CLI フラグではありません。ジョブでは、平面図ビューの camera ({"target": [x, y, 0], "position": [x, y, d], "up": [0, 1, 0], "orthographicHalfHeight": h})で図面の一部を表示し、その上に図面座標で annotation を描画できます。Quick Edit のプロンプトの views ファイルはこの形式のジョブです。cadgen dxf snapshot --job <it> を実行すると、ユーザーが見たビューを再度レンダリングします。 これ以外のカメラ位置、出力ごとのカメラ、シーン表示の設定、scale、リストモード、 出力の label/viewLabel、output.padding/viewLabels/tightFrame は拒否されます。 ジョブの output.renderScale と output.transparent は引き続き適用されます。 Quick Edit では、このデータを JSON としてインラインで渡すか、.snapshot.json パスで指定します。--job を使う前に、インライン JSON を一時ファイルに保存してください。編集する前に、指定されたアノテーションを確認してください。アノテーションがない場合、キャプチャされたビューは任意の参考情報です。

既存の .dxf を調べる CLI はありません。エンティティやレイヤーを確認するには、ezdxf(build123d に含まれます)で直接読み込み、図面のチェックには validate_dxf_file を使用してください。形状は目視で確認してください(モデルを表示するを参照)。

ワークフロー

  1. 依頼内容を簡潔な要件にまとめます。外形寸法、穴やスロット、レイヤー、単位、出力パス、検証対象を記載します。
  2. ワークフローを選びます。ゼロから作図する、生成したモデルのフラットパターンを作成する(まず $cad で 3D 形状を作成して検証します)、またはインポートした STEP のフラットパターンを作成します。
  3. 意味のある寸法を名前付き定数として使用し、数式を重複させずにモデルの形状ヘルパーを再利用して、<name>.py ソースを作成または編集します。
  4. 各図面スクリプトを直接実行します(python <drawing>.py)。ディレクトリを一括処理しないでください。
python path/to/source.py
python path/to/source.py --force
  1. 生成された DXF を決定的に検証してから、引き渡し、結果を報告します。

モデルの表示

作成または変更した各ファイルと、ユーザーから表示を求められたファイルを提示してください。スナップショットや検証で、これを代替することはできません。

  • ツールに cad_show(ホストによっては前にプレフィックスが付く場合があります)が含まれている場合は、ファイルの絶対パスを指定して使用し、再度呼び出すタイミングについてはその説明に従ってください。cad_view はユーザーが選択した内容を読み取り、cad_screenshot はユーザーに見える内容を表示します。どちらも自分の作業のレビューには使えません。

  • それ以外の場合は、任意のフォルダーから CAD Viewer を実行します。

    cadgen viewer --host 127.0.0.1 --json --detach
    

    --detach を指定すると、ビューアーがリクエストに応答できる状態になった時点で戻り、バックグラウンドで実行を続けます。フォアグラウンドのビューアーは終了しないため、必ず指定してください(出力を tail にパイプすると、URL が完全に隠れてしまうこともあります)。このマシンで 1 つのビューアーを起動するか、既存のものを再利用します。1 行の JSON から url を読み取り(ポート番号を推測しないでください)、各ファイルについて url?file=<そのファイルのURLエンコードされた絶対パス> を返してください。起動に失敗した場合は、その旨を伝えてください。

ビューアーは保存済み DXF ファイルを読み取り専用の 2D 図面として表示し、生成スクリプトは実行しません。ドラッグでパン、ホイールまたはピンチでズーム、ダブルクリックで全体表示します。ビューアーの Select、Pencil、Shapes、Measure は Quick Edit に入力を送ります。そのプロンプトは、選択したものを参照として、エンティティの HANDLE で図面内の位置を示します。panel.dxf#h2F は、ハンドルが 2F のモデル空間エンティティ(ezdxf では doc.entitydb["2F"])を示します。ブロック参照が描画するものは INSERT で示され、寸法は 1 つのエンティティです。プロンプトのチップには、エンティティのタイプとレイヤーが「Circle on CUT」のように表示されます。測定値の単位は $INSUNITS で宣言された単位です(宣言がない場合は「units」)。

検証

検証は生成後ではなく、生成中に行われます。すべての @dxf ビルドで、エンジンが直前にシリアライズしたドキュメントに対して図面チェックを実行してから書き込みを行い、エラーの検出結果があるビルドは失敗します。チェック内容は次のとおりです。切断レイヤーの輪郭は閉じている必要があります(ポリライン、円、または連結された線分/円弧のループ)。長さがゼロまたは退化したエンティティは拒否されます。完全に重複するジオメトリ(重複切断のリスク)は拒否されます。単位が明示的に未設定のドキュメントは拒否されます。空のモデル空間は拒否されます。開いたジオメトリが許可されるのは、曲げ/刻印/参照用途のレイヤーのみです(名前で判定)。

同じチェックは、生成ツールで作成されたものかどうかを問わず、既存の .dxf ファイルに対しても cadgen.drawing_checks を通じて事後に実行されます。

from cadgen.drawing_checks import validate_dxf_file

for finding in validate_dxf_file("path/to/file.dxf"):
    print(finding.render())

組み込みチェックに加え、生成された同階層の .dxf(または out= で指定されている場合はそのパス)に対して、対象を絞った ezdxf の読み取り(レイヤーごとのエンティティ数、図面の範囲、ユーザーが指定したすべての寸法)で要求された寸法を検証し、CAD Viewer でジオメトリを目視確認してください。

import ezdxf

doc = ezdxf.readfile("path/to/source.dxf")
msp = doc.modelspace()
cut = msp.query('*[layer=="CUT"]')
holes = msp.query('CIRCLE[layer=="CUT"]')

実際に実行したチェックのみを報告してください。

引き継ぎ

作成または変更したすべての図面を表示してください(モデルの表示)。失敗があれば、必ず明示してください。

最終回答には、生成したファイル、返されたビューアーのリンク、実際に実行した検証、および前提条件を含めてください。

コメント