現在の作業内容
Penplot-Gcoder — CLAUDE.md
プロジェクトルール
このファイルはClaude Codeが会話をまたいで参照する設計仕様・進捗・編集履歴の唯一の情報源。
以下のルールを常に守ること:
- 仕様変更があるたびに、このファイルの該当セクションを即座に更新する
- 実装作業のたびに「進捗状況」セクションを更新する
- すべての変更を「編集履歴」に日付・内容・理由とともに記録する
- 実装前に必ずこのファイルを読み、仕様と現状を把握してから作業する
- 仕様に曖昧な点があればユーザーに確認してから実装する
プロジェクト概要
3Dプリンターをペンプロッターとして使用するための、2Dベクター画像からGコードを生成するデスクトップアプリケーション。
ペンはプリンターノズルにオフセットして取り付ける前提。
技術スタック
| 項目 |
採用技術 |
| 言語 |
Python 3.10+ |
| GUI |
PyQt6 |
| 3Dプレビュー |
pyqtgraph GLViewWidget (確定) |
| 2Dプレビュー |
PyQt6 QPainter |
| ベクター処理 |
svgpathtools / ezdxf |
| 数値計算 |
numpy |
| 形状演算 |
Shapely |
| PNG/JPG輪郭抽出 |
opencv-python (cv2) |
対応入力ファイル形式
- SVG (メイン)
- DXF
- PNG / JPG (輪郭抽出によるベクター変換)
画面構成
┌─────────────────────────────────────────────────────┐
│ メニューバー [ファイル] [編集] [表示] [ヘルプ] │
├──────────┬──────────────────────────────────────────┤
│ │ [2D表示] [3D表示] [アニメーション ▶] │
│ 設定 ├──────────────────────┬───────────────────┤
│ パネル │ │ │
│ │ プレビューエリア │ パス リスト │
│(タブ式) │ (2D or 3D) │ │
│ │ │ │
├──────────┴──────────────────────┴───────────────────┤
│ 有効描画エリア: 205×215mm [警告: はみ出しあり] │
├─────────────────────────────────────────────────────┤
│ [ファイルを開く] [Gコード生成] [保存] │
├─────────────────────────────────────────────────────┤
│ ステータス: パス数 48 / 推定時間 12m34s / 移動 1823mm │
└─────────────────────────────────────────────────────┘
仕様詳細
Machine タブ — プリンター設定
| パラメータ |
デフォルト |
説明 |
| プリンタープロファイル |
カスタム |
Ender-3 / Prusa MK3 / カスタム |
| ファームウェア |
Marlin |
Marlin / Klipper |
| ベッドサイズ X |
220mm |
描画可能エリア幅 (=用紙幅の上限) |
| ベッドサイズ Y |
220mm |
描画可能エリア奥行き (=用紙高さの上限) |
| 原点位置 |
左下 |
ベッド上の基準点 (左下 / 中央) |
| 有効描画エリア |
自動計算・読み取り専用 |
ペンオフセットを差し引いた実効エリア |
用紙サイズはベッドサイズで決まる。 別途「用紙サイズ」設定はない。
有効描画エリアの計算式
X_min = max(0, -offset_x)
X_max = min(bed_x, bed_x - offset_x)
Y_min = max(0, -offset_y)
Y_max = min(bed_y, bed_y - offset_y)
有効幅 = X_max - X_min
有効高さ = Y_max - Y_min
- オフセット変更時にリアルタイムで再計算・表示更新
- 配置がはみ出す場合は警告バナー表示・Gコード生成をブロック
- プレビュー: ベッド枠(グレー)と有効描画エリア枠(緑)を区別表示
Pen タブ — ペン設定
ペン動作
| パラメータ |
デフォルト |
説明 |
| ペン下げ Z 高さ |
0.0mm |
紙に接触する Z 座標 |
| ペン上げ Z 高さ |
5.0mm |
移動時のリフト量 |
| ペン下げ速度 |
300 mm/min |
Z 軸の下降速度 |
| ペン上げ速度 |
1000 mm/min |
Z 軸の上昇速度 |
| タッチダウン後ディレイ |
0ms |
ペン下げ完了後・描画開始前の待機時間 (G4 P)。バウンド収束に使用 |
| リフトアップ前ディレイ |
0ms |
ペン上げ直前の待機時間 (G4 P)。筆跡乾き待ちにも使用可 |
ペンオフセット(ノズルからの取り付けオフセット)
| パラメータ |
デフォルト |
説明 |
| オフセット X |
0.0mm |
ノズル基準でのペン先X方向ずれ |
| オフセット Y |
0.0mm |
ノズル基準でのペン先Y方向ずれ |
| オフセット Z |
0.0mm |
ノズル基準でのペン先Z方向ずれ |
- 生成Gコードの全XYZ座標にオフセットを自動加算
- プレビューはオフセット後の実座標で表示
- オフセット変更時に有効描画エリアを連動して再計算
Speed タブ — 速度設定
| パラメータ |
デフォルト |
説明 |
| 描画速度 |
1500 mm/min |
ペン下げ状態でのXY移動速度 |
| 移動速度 |
6000 mm/min |
ペン上げ状態でのXY移動速度 |
| 加速度 |
1000 mm/s² |
M204 で設定する加速度 |
| コーナー速度 |
5 mm/s |
M205 ジャーク設定 |
Path タブ — パス処理
スケール・配置
| パラメータ |
デフォルト |
説明 |
| スケール |
100% |
図形の拡大縮小 |
| X オフセット |
0mm |
ベッド上の配置位置 |
| Y オフセット |
0mm |
ベッド上の配置位置 |
| 回転 |
0° |
図形の回転 |
| 中央揃え |
ボタン |
有効描画エリアの中央に自動配置 |
パス最適化
| パラメータ |
デフォルト |
説明 |
| パス最適化 |
有効 |
移動距離最小化のためのパス順序並び替え |
| 最適化アルゴリズム |
Greedy |
Greedy (最近傍) / 2-opt |
| パス結合距離 |
0.5mm |
この距離以内の端点を自動結合しペン上げ削減 |
| カーブ分解精度 |
0.1mm |
ベジェ曲線のポリライン変換精度 |
Fill タブ — 塗りつぶし設定
SVGの塗りつぶし領域やクローズドパスに対してハッチングパターンを生成する。
基本設定
| パラメータ |
デフォルト |
説明 |
| 塗りつぶし有効 |
無効 |
塗りつぶしを生成するか |
| 対象 |
塗りつぶし色あり |
すべてのクローズドパス / 塗りつぶし色ありのみ |
| レイヤー順 |
輪郭→塗りつぶし |
輪郭先 / 塗りつぶし先 / 塗りつぶしのみ |
パターン種別
| パターン名 |
概要 |
| Lines |
平行ライン |
| Cross Hatch |
2方向クロスハッチング |
| Tri Hatch |
3方向 (0°/60°/120°) ハッチング |
| Contour Offset |
輪郭を内側に等間隔オフセット (同心状) |
| Zigzag |
ジグザグ往復ライン |
| Dots |
等間隔の点描 |
| Spiral |
輪郭から内側へのスパイラル (円形領域向け) |
パターン共通パラメータ
| パラメータ |
デフォルト |
説明 |
| 線間隔 |
1.0mm |
ハッチングラインの間隔 |
| 角度 |
45° |
ライン方向の角度 (Lines / Zigzag 用) |
| 輪郭との余白 |
0.0mm |
塗りつぶし開始位置を輪郭から何mm内側にするか |
| パス最適化 |
有効 |
塗りつぶしパスも移動距離最小化 |
Cross Hatch 追加パラメータ
| パラメータ |
デフォルト |
説明 |
| 第2角度オフセット |
90° |
2本目のライン方向 (第1角度 + オフセット) |
Contour Offset 追加パラメータ
| パラメータ |
デフォルト |
説明 |
| 最内ライン処理 |
そのまま |
そのまま / 省略 / 点描 |
Dots 追加パラメータ
| パラメータ |
デフォルト |
説明 |
| 点の配置 |
グリッド |
グリッド / 千鳥 |
| 点の間隔 Y |
1.0mm |
Y方向の間隔 (X方向は「線間隔」を使用) |
GCode タブ — Gコードカスタマイズ
開始コード (Start G-code)
テキストエディタで自由に編集可能。
; デフォルト
G28
G90
G21
G1 Z{pen_up_z} F{pen_up_speed}
終了コード (End G-code)
; デフォルト
G1 Z{pen_up_z} F{pen_up_speed}
G1 X0 Y0 F{travel_speed}
M84
ペン上げ/下げコード (カスタマイズ可)
| 項目 |
デフォルト |
| ペン上げコード |
G1 Z{pen_up_z} F{pen_up_speed} |
| ペン下げコード |
G1 Z{pen_down_z} F{pen_down_speed} |
サーボや専用ピンを使う場合にここを差し替える。
利用可能なプレースホルダー
| 変数 |
内容 |
{pen_down_z} |
ペン下げZ高さ |
{pen_up_z} |
ペン上げZ高さ |
{pen_down_speed} |
ペン下げ速度 |
{pen_up_speed} |
ペン上げ速度 |
{draw_speed} |
描画速度 |
{travel_speed} |
移動速度 |
{offset_x} / {offset_y} / {offset_z} |
ペンオフセット |
{bed_x} / {bed_y} |
ベッドサイズ |
{touchdown_delay} |
タッチダウン後ディレイ (ms) |
{liftup_delay} |
リフトアップ前ディレイ (ms) |
プレビュー機能
2Dビュー
| 要素 |
表示 |
| 描画パス (ペン下げ) |
実線 (青) |
| 移動パス (ペン上げ) |
点線 (赤) |
| ベッド枠 |
グレー |
| 有効描画エリア枠 |
緑 |
操作: ホイールズーム / ドラッグパン
3Dビュー
| 要素 |
色 |
| 描画パス (ペン下げ) |
青 |
| 移動パス (ペン上げ) |
赤点線 |
| ペン下げ動作 (Z軸垂直線) |
緑 |
| ペン上げ動作 (Z軸垂直線) |
オレンジ |
| ベッド面 |
半透明グリッド・グレー |
| 有効描画エリア枠 |
緑 |
| 操作 |
動作 |
| 左ドラッグ |
回転 |
| 中/右ドラッグ |
パン |
| ホイール |
ズーム |
| Numpad 7 |
真上 (XY平面) |
| Numpad 1 |
正面 (XZ平面) |
| Numpad 3 |
側面 (YZ平面) |
| R |
視点リセット |
| パラメータ |
デフォルト |
説明 |
| Z軸誇張倍率 |
10× |
Z方向を誇張表示するスケール係数 |
共通
- パス順序アニメーション再生 (2D / 3D 両対応)
- 3DビューのZ動作もアニメーションで再現
生成Gコードの構造
; === Penplot-Gcoder ===
; 入力: example.svg
; 生成: 2026-03-06
; ベッド: 220x220mm ペンオフセット: X=15.0 Y=0.0 Z=0.0
; 有効描画エリア: 205x220mm
; パス数: 48 / 推定描画時間: 12m34s
; ---- START G-CODE ----
G28
G90
G21
G1 Z5.0 F1000
; ---- DRAW ----
; パス 1/48
G1 Z5.0 F1000
G1 X25.0 Y20.0 F6000 ; オフセット加算済み (元: X10.0 Y20.0)
G1 Z0.0 F300 ; ペン下げ
G4 P50 ; タッチダウン後ディレイ 50ms
G1 X65.0 Y20.0 F1500 ; 描画
G4 P0 ; リフトアップ前ディレイ
G1 Z5.0 F1000 ; ペン上げ
...
; ---- END G-CODE ----
G1 Z5.0 F1000
G1 X0 Y0 F6000
M84
プロファイル管理
- プリンタープロファイル:
profiles/printers/*.json
- ユーザー設定:
profiles/user/*.json
- プリセット例: 「細字ペン」「太字マーカー」「鉛筆」「高精度」
プロジェクト構成
Penplot-Gcoder/
├── main.py # エントリーポイント
├── requirements.txt
├── CLAUDE.md
├── profiles/
│ ├── printers/ # プリンタープロファイル JSON
│ └── user/ # ユーザー保存プロファイル JSON
├── src/
│ ├── __init__.py
│ ├── app.py # QApplication・メインウィンドウ初期化
│ ├── ui/
│ │ ├── __init__.py
│ │ ├── main_window.py # メインウィンドウ・レイアウト
│ │ ├── settings_panel.py# 左設定パネル (タブ式)
│ │ ├── preview_2d.py # 2Dプレビューウィジェット (QPainter)
│ │ ├── preview_3d.py # 3Dプレビューウィジェット (pyqtgraph GL)
│ │ └── path_list.py # 右パスリストウィジェット
│ ├── core/
│ │ ├── __init__.py
│ │ ├── importer/
│ │ │ ├── svg_importer.py
│ │ │ ├── dxf_importer.py
│ │ │ └── image_importer.py # PNG/JPG → 輪郭抽出 (cv2)
│ │ ├── path_optimizer.py # Greedy / 2-opt 最適化
│ │ ├── fill_generator.py # 塗りつぶしパターン生成
│ │ ├── gcode_generator.py # Gコード生成エンジン
│ │ └── bed_calculator.py # 有効描画エリア計算
│ └── models/
│ ├── __init__.py
│ ├── settings.py # 全設定のデータモデル (dataclass)
│ └── pen_path.py # パスデータ構造
SVG複数色の扱い
- SVGの各パスの
stroke / fill 色を読み取り、色ごとにグループ化してパスリストに表示
- ユーザーはパスリストで各グループの描画順序を並び替え可能
- 色グループ = 「ペン交換タイミング」として扱い、グループ間に
M0 (カスタム一時停止コード) を挿入するオプションを追加
Undo/Redo
- 配置・スケール・回転などの操作に対して Undo/Redo (Ctrl+Z / Ctrl+Y) をサポート
- PyQt6 の QUndoStack を使用
requirements.txt (確定版)
PyQt6>=6.4.0
pyqtgraph>=0.13.0
numpy>=1.24.0
Shapely>=2.0.0
svgpathtools>=1.6.0
ezdxf>=1.0.0
opencv-python>=4.8.0
進捗状況
| フェーズ |
タスク |
状態 |
| 仕様策定 |
基本仕様 (v1) |
完了 |
| 仕様策定 |
塗りつぶし・オフセット・GCodeカスタマイズ追加 (v2) |
完了 |
| 仕様策定 |
タッチダウンディレイ・有効エリア連動・3Dプレビュー追加 (v3) |
完了 |
| 仕様策定 |
3Dプレビューの実装ライブラリ選定 |
完了 (pyqtgraph) |
| 実装 |
プロジェクト構成・雛形作成 |
完了 |
| 実装 |
GUIレイアウト (PyQt6) |
完了 |
| 実装 |
SVG読み込み・パス変換 |
完了 |
| 実装 |
DXF読み込み |
完了 |
| 実装 |
PNG/JPG輪郭抽出 |
完了 |
| 実装 |
2Dプレビュー |
完了 |
| 実装 |
3Dプレビュー |
完了 |
| 実装 |
パス最適化 (Greedy / 2-opt) |
完了 |
| 実装 |
塗りつぶしパターン生成 |
完了 |
| 実装 |
Gコード生成エンジン |
完了 |
| 実装 |
ペンオフセット・有効エリア計算 |
完了 |
| 実装 |
GCodeタブ (開始・終了コードエディタ) |
完了 |
| 実装 |
プロファイル管理 |
完了 |
| 実装 |
シークバー (再生/一時停止) |
完了 |
| 実装 |
Raw ビュー修正 (スケール適用後表示) |
完了 |
| 実装 |
複数ファイル同時インポート |
完了 |
| 実装 |
設定自動保存 (autosave.json / デバウンス1秒) |
完了 |
| 実装 |
プロファイル追加・保存・削除 (全設定対応) |
完了 |
| 実装 |
.gitignore 作成 |
完了 |
| 実装 |
Raw ビュー GIMP 風キャンバス (src/ui/raw_view.py) |
完了 |
| 実装 |
配置コントロール (Scale/X/Y/R/中央) を Raw タブ限定に変更 |
完了 |
| 実装 |
Raw 画像モードにベッドサイズ・有効エリアオーバーレイ追加 |
完了 |
| 実装 |
レイヤー管理 (ファイル単位・表示/非表示・並び替え) |
完了 |
| 実装 |
Raw タブ描画ツール (フリーハンド/パス/直線/矩形/楕円) + src/ui/raw_toolbar.py |
完了 |
| 実装 |
描画レイヤー (ユーザー作成・追加/削除/リネーム) + アクティブレイヤー選択 |
完了 |
| 実装 |
PenPath.stroke_width_mm 追加 (描画ストローク幅保持・プレビュー表示反映) |
完了 |
編集履歴
| 日付 |
バージョン |
変更内容 |
理由 |
| 2026-03-06 |
v1 |
基本仕様策定。技術スタック・画面構成・Machine/Pen/Speed/Path/Fill/GCodeタブの初版 |
プロジェクト開始。Kasynel-Slicerを参考に設計 |
| 2026-03-06 |
v2 |
用紙サイズをベッドサイズ依存に変更。開始/終了Gコードをユーザー編集可能に。ペンオフセット(X/Y/Z)追加。塗りつぶしパターン詳細化 (Lines/CrossHatch/TriHatch/ContourOffset/Zigzag/Dots/Spiral) |
ユーザー要件追加 |
| 2026-03-06 |
v3 |
タッチダウン後ディレイ・リフトアップ前ディレイ追加。ペンオフセット連動の有効描画エリア自動計算追加。3Dプレビュー機能追加 (Z軸誇張倍率・視点ショートカット・アニメーション) |
ユーザー要件追加 |
| 2026-03-06 |
v4 |
3Dプレビューライブラリをpyqtgraphに確定。2DプレビューをQPainterに確定。PNG/JPG処理をcv2に確定。プロジェクトファイル構成追加。SVG複数色グループ対応追加。Undo/Redo (QUndoStack) 追加。requirements.txt確定。 |
ユーザー承認・実装開始前の仕様確定 |
| 2026-03-06 |
v5 |
全機能を実装完了。main.py / src/ ディレクトリ全体 / profiles/ を新規作成。models (settings.py, pen_path.py)、core (bed_calculator, path_optimizer, fill_generator, gcode_generator, importers)、ui (main_window, settings_panel, preview_2d, preview_3d, path_list) を実装。 |
実装完了 |
| 2026-03-07 |
v6 |
main.py に自動パッケージインストール機能追加 (_check_and_install)。setup.bat 作成 (pip install + python main.py を一括実行)。 |
初回セットアップの簡略化 |
| 2026-03-07 |
v9 |
シークバー追加 (▶/⏸ ボタン + QSlider でパス再生)。複数ファイル同時インポート対応 (getOpenFileNames)。設定自動保存機能追加 (profiles/user/autosave.json に1秒デバウンス保存、起動時自動復元)。プロファイル管理強化 (New/Save/Delete ボタン追加、全 AppSettings を JSON 保存/読み込み、path placement は保持)。.gitignore 作成 (profiles/user/ を除外)。 |
ユーザー要件追加 |
| 2026-03-07 |
v10 |
Raw ビューを GIMP 風 QGraphicsView キャンバスに全面リニューアル (src/ui/raw_view.py 新規作成)。画像: 元画像+チェッカーボード+輪郭オーバーレイ、抽出パラメーターをリアルタイム変更可能。ベクター: 元座標でパスを表示、クリック選択・Delete 削除。ホイールズーム/ドラッグパン対応。画像ベクター変換は Generate ボタン押下時に遅延実行。Generate ボタンが押せる状態なら点滅 (パルスアニメーション)。設定変更で Preview データ破棄・Generate 待機。Generate 完了で自動的に Preview タブへ移行。Raw ではベクターは Preview2D でドラッグ配置可能。"変換後" タブ名を "Preview" に変更。 |
ユーザー要件 |
| 2026-03-07 |
v7 |
UI をタブベース5ステップフロー (① 配置 / ② 設定 / ③ 生成 / ④ 確認 / ⑤ 出力) に再構築。ファイルパス問題 (日本語・記号・長パス) を一時コピーで修正 (_safe_filepath)。自動フィット・カーソル座標・ドラッグ操作は配置タブに統合。 |
ユーザー要件追加 |
| 2026-03-07 |
v8 |
UIをChituboxライクな1画面構成に全面再設計。左=設定パネル/中央=プレビュー(Raw 2D・変換後 2D・3D切り替え)/右=パスリスト+統計/下部バー=配置コントロール+アクションボタン。ファイル読み込み時にRaw→変換後を自動切り替えで両方確認できる。 |
ユーザー要件変更 |
| 2026-03-07 |
v11 |
配置コントロール (Scale/X/Y/R/中央/ドラッグ) を Raw タブ限定に変更 (Preview・3D タブでは無効化)。Raw 画像モードに mm 単位ベッド境界・有効エリアオーバーレイを追加 (設定変更でリアルタイム更新)。_source_groups+_source_files を _layers 構造 [{name,filepath,groups,visible}] に置き換え。PathListPanel をレイヤー対応に全面改修 (ファイル単位レイヤーヘッダー・表示/非表示チェックボックス・グループ並び替え)。 |
ユーザー要件: Raw でのみ配置操作・ベッドサイズ表示・レイヤー管理 |
| 2026-03-08 |
v12 |
Raw タブにツールバー (src/ui/raw_toolbar.py) を追加。描画ツール: フリーハンド(✏)・パス(📐)・直線・矩形・楕円、ストローク幅(mm)/色選択付き。Preview2D に全描画ツール対応の mouse イベント処理を追加 (path_drawn シグナル)。描画ストロークはアクティブな描画レイヤーへ追加。PathListPanel にアクティブレイヤー選択 (クリック)・リネーム (ダブルクリック)・追加 (+)/削除 (−) ボタンを追加。PenPath に stroke_width_mm フィールドを追加。 |
ユーザー要件: Raw モードで直感的な描画・ペイントソフト風レイヤー管理 |