3D Gaussian Splatting (3DGS) のデータを Stratasys J850 Prime などのマルチマテリアル3Dプリンター用のボクセルスライスデータに変換するPythonツールです。
このツールは論文『DreamPrinting』の手法に基づき、以下の処理を行います:
- PLYファイルの読み込み - 3DGSの点群データを読み込む
- ボクセル化 - 点群を規則的な3Dグリッドにリサンプリング
- 物理インク変換 - RGB色と密度を6種類の物理インク(CMYK + White + Clear)の濃度に変換
- 確率的ハーフトーニング - 連続的なインク濃度を離散的なラベルに変換
- 可視化 - Rerun SDKを使用してインタラクティブに結果を確認
- スライス出力 - Z軸方向のスライス画像(PNG連番)を生成
- Python 3.8以上
- pip
# リポジトリをクローンまたはダウンロード
cd 3dgs-to-printer
# 依存パッケージをインストール
pip install -r requirements.txtWebブラウザで直感的に操作できるGUIアプリケーションです:
python gui_app.pyブラウザが自動的に開き、以下の操作が可能:
- ✅ ファイルをドラッグ&ドロップでアップロード
- ✅ スライダーで簡単パラメータ調整
- ✅ クリッピング設定をGUIで指定
- ✅ リアルタイム処理ログ表示
詳細: GUI_GUIDE.md を参照
3Dビューで視覚的にクリッピング領域を設定できる高度なGUIです:
python gui_app_3d.py標準GUI版の全機能に加えて:
- ✨ Plotly 3Dプレビュー - マウスで回転・ズーム可能な3D表示
- 🎯 視覚的クリッピング設定 - オレンジ色のワイヤーフレームで領域を確認
- 📍 自動設定ボタン - データ中心やサイズを自動計算
- 👁️ リアルタイムプレビュー - 設定変更を即座に3D上で確認
詳細: GUI_3D_GUIDE.md を参照
コマンドラインから実行する従来の方法です:
python 3dgs_to_printer.py input.plyこれにより、以下が実行されます:
input.plyを 0.3mm のボクセルサイズで変換- Rerun で可視化ウィンドウが開く(複数の密度スケールをタイムラインで確認可能)
./print_slices/ディレクトリにスライス画像を出力
3DGSファイルの形状情報(楕円体、回転、不透明度)を正確に評価:
python 3dgs_to_printer.py input.ply --high-precision利点:
- ガウシアンの楕円形状を考慮(薄い壁や床が正しく表現される)
- 不透明度を正確に反映
- マハラノビス距離による高精度な密度計算
詳細: HIGH_PRECISION_MODE.md を参照
大きなシーンから特定の領域のみを切り抜いて印刷:
# Box(直方体)クリッピング
python 3dgs_to_printer.py input.ply \
--high-precision \
--clip-mode box \
--clip-center 0 0 0 \
--clip-size 20 20 30
# Sphere(球体)クリッピング
python 3dgs_to_printer.py input.ply \
--high-precision \
--clip-mode sphere \
--clip-center 0 0 0 \
--clip-radius 15利点:
- 処理時間の短縮(不要な部分を除外)
- メモリ使用量の削減
- 関心領域に集中した高品質出力
詳細: CLIPPING_GUIDE.md を参照
3DGS座標を実際の印刷サイズ(mm)に変換:
# 例: 3DGSの1単位 = 10mm
python 3dgs_to_printer.py input.ply \
--high-precision \
--printing-scale 10.0Y-upからZ-upへの変換など:
python 3dgs_to_printer.py input.ply \
--high-precision \
--coordinate-transform y_to_zpython 3dgs_to_printer.py input.ply \
--voxel-size 0.2 \
--density-scales 0.5 1.0 2.0 \
--export-scale 1.0 \
--output-dir ./output \
--k-neighbors 8 \
--seed 42| パラメータ | デフォルト | 説明 |
|---|---|---|
--voxel-size |
0.3 | ボクセルサイズ (mm) - 高解像度: 0.1-0.5mm - 中解像度: 0.5-2mm - 低解像度: 2-5mm |
--density-scales |
0.5 0.75 1.0 1.5 2.0 | Rerunで可視化する密度スケール係数のリスト |
--export-scale |
1.0 | 最終出力に使用する密度スケール係数 |
--output-dir |
./print_slices | スライス画像の出力先ディレクトリ |
--k-neighbors |
8 | k-NN補間の近傍点数(高精度モードでは16推奨) |
--seed |
42 | 確率的ハーフトーニングのランダムシード |
--no-visualize |
False | Rerun可視化をスキップ |
--high-precision |
False | 高精度ガウシアンボクセライザを使用(形状・回転・不透明度を考慮) |
--clip-mode |
none | クリッピングモード: box, sphere, cylinder, none |
--clip-center |
- | クリッピング領域の中心座標 (x y z) |
--clip-size |
- | Box クリッピングの寸法 (w h d) |
--clip-radius |
- | Sphere/Cylinder クリッピングの半径 |
--printing-scale |
1.0 | 3DGS単位からmmへのスケール係数(例: 10.0 = 1単位が10mm) |
--coordinate-transform |
none | 座標系回転: none, x_to_z, y_to_z, z_to_y |
点群データを規則的な3Dグリッドに変換します。各グリッド点について、k-NN(k最近傍)探索により近傍の点から色と密度を補間します。
# 密度の推定方法
# 各点の周辺(voxel_size範囲内)にある点の数から密度を計算
density = log(neighbor_count + 1)RGB色と密度を物理インクの濃度に変換します。簡易Kubelka-Munkモデルを使用:
# ステップ1: RGB → CMY変換(減法混色)
CMY = 1 - RGB
# ステップ2: 黒成分(K)の抽出
K = min(C, M, Y)
C, M, Y = C - K, M - K, Y - K
# ステップ3: 白成分(W)の計算
W = brightness(RGB) * 0.5
# ステップ4: 密度による調整
密度が高い → 有色インク(CMYKW)の比率を高める
密度が低い → Clearインクの比率を高める
# ステップ5: 正規化
各ボクセルの6種類のインク濃度の合計が1になるよう正規化各ボクセルに対して、インク濃度を確率として扱い、1つのインクラベルを決定します:
# 例: C=0.2, Clear=0.8 の場合
# 20%の確率でCyan、80%の確率でClearを選択
cumsum = cumsum([0.8, 0.2, ...]) # = [0.8, 1.0, ...]
rand = random() # 0.0 ~ 1.0
label = search_sorted(cumsum, rand)Rerun SDKを使用して、複数の密度スケールの結果を可視化します:
- タイムラインスライダー: 異なる密度スケール(0.5x, 0.75x, 1.0x, 1.5x, 2.0x)を切り替えられます
- 3Dポイントクラウド: 各ボクセルが決定されたインクの色で表示されます
- 統計情報: 各インクの使用割合がテキストで表示されます
最終的なボクセルグリッドをZ軸方向でスライスし、PNG画像として出力します。
GrabCAD Printなどのプリンタードライバーが認識できるように、各インクを特定のRGB値にマッピングします:
| インク | RGB値 |
|---|---|
| Clear | (255, 255, 255) 白 |
| Cyan | (0, 255, 255) シアン |
| Magenta | (255, 0, 255) マゼンタ |
| Yellow | (255, 255, 0) イエロー |
| Black | (0, 0, 0) 黒 |
| White | (128, 128, 128) グレー* |
*White インクは Clear と区別するためグレー (128, 128, 128) を使用します。
print_slices/
├── slice_0000.png
├── slice_0001.png
├── slice_0002.png
...
└── slice_NNNN.png
各PNG画像は、Z軸の対応する高さでのXY平面スライスを表します。
- スクリプトを実行すると、Rerunの可視化ウィンドウが自動的に開きます
- タイムラインスライダー(画面下部)を使用して、異なる密度スケールを確認できます
- 50 = 0.5x
- 75 = 0.75x
- 100 = 1.0x
- 150 = 1.5x
- 200 = 2.0x
- 左側のパネルで統計情報を確認し、各インクの使用割合を把握できます
- 最適な密度スケールを見つけたら、
--export-scaleパラメータで指定して再実行してください
ボクセル数が多すぎる場合、メモリ不足になる可能性があります。
解決策:
--voxel-sizeを大きくする(例: 0.3 → 0.5)- より小さい点群データを使用する
解決策:
--voxel-sizeを大きくする--k-neighborsを減らす(例: 8 → 4)--no-visualizeを使用してRerun可視化をスキップ
解決策:
--density-scalesで複数のスケールを試す--export-scaleを調整する(通常 0.5 ~ 2.0 の範囲)- 入力PLYファイルの色情報を確認する
- 入力: PLY形式(点群 + RGB色)
- 出力: PNG画像連番(8-bit RGB)
- ボクセル化: k-NN補間(scipy.spatial.cKDTree)
- 色変換: 簡易Kubelka-Munkモデル
- ハーフトーニング: 確率的サンプリング(NumPy RNG)
処理時間はボクセル数に依存します:
| ボクセル数 | 処理時間(目安) |
|---|---|
| 100³ = 1M | ~1分 |
| 200³ = 8M | ~5分 |
| 300³ = 27M | ~15分 |
*Intel Core i7, 16GB RAM での測定値
PigmentDef
├─ CLEAR, CYAN, MAGENTA, YELLOW, BLACK, WHITE (定数)
├─ DISPLAY_COLORS (Rerun表示用)
└─ EXPORT_COLORS (PNG出力用)
PigmentMapper
└─ rgb_density_to_concentration(rgb, density, scale)
→ RGB+密度 → 6次元インク濃度ベクトル
Voxelizer
└─ resample_to_grid(ply_path, voxel_size)
→ PLY → ボクセルグリッド(RGB + 密度)
StochasticHalftoner
└─ halftone(concentrations)
→ 連続濃度 → 離散ラベル
VoxelExporter
└─ export_slices(voxel_labels, dims, output_dir)
→ ボクセルラベル → PNG連番
- DreamPrinting: Towards Photorealistic Material Appearance Transfer for 3D Printing
- Kubelka-Munk Theory for Subtractive Color Mixing
- Stochastic Halftoning for Multi-Material 3D Printing
MIT License
Generated for 3DGS Printing Project
注意: このツールは研究・実験目的で作成されています。実際の3Dプリント前に、小さなテストモデルで結果を確認することをお勧めします。