[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-92577":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":14,"stars7d":14,"stars30d":15,"stars90d":14,"forks30d":14,"starsTrendScore":14,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":14,"starSnapshotCount":14,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},92577,"image-3d","animede\u002Fimage-3d","animede","image to 3d for 3D-printer",null,"Python",141,18,69,0,73,51.14,"Other",false,"master",true,[],"2026-07-22 04:02:06","# Image-3D\n\n画像から3Dプリントデータ(STL \u002F 3MF \u002F GLB \u002F OBJ)を生成するローカルWebアプリ。\n\nWeb UIの使い方は [`docs\u002FUSAGE.md`](docs\u002FUSAGE.md)、詳細仕様は\n[`docs\u002FSPEC.md`](docs\u002FSPEC.md)、開発方針は\n[`docs\u002FDEVELOPMENT_POLICY.md`](docs\u002FDEVELOPMENT_POLICY.md)、実装計画は\n[`docs\u002FIMPLEMENTATION_PLAN.md`](docs\u002FIMPLEMENTATION_PLAN.md) を参照。\n\nバグ報告・機能要望は [Issues](https:\u002F\u002Fgithub.com\u002Fanimede\u002Fimage-3d\u002Fissues)、\nコントリビューションは [CONTRIBUTING.md](CONTRIBUTING.md) を参照してください。\n\n## 現在の状態(Phase 1〜3b)\n\n- Image-to-3D 生成は **mockジェネレータ**(決定的なパラメトリックメッシュ)を使用。\n- GPU \u002F Hunyuan3D-2 は未導入でも、アップロード → 生成 → メッシュ後処理 →\n  3Dビューア表示 → STL\u002F3MF\u002FGLB\u002FOBJ ダウンロードの全パイプラインがE2Eで動作する。\n- Phase 2 で `IMAGE3D_GENERATOR=hunyuan3d` により実モデルに切り替え可能(下記参照)。\n- Phase 2.5 で4色カラープリンタ向け出力(`color_mode=color4`)に対応\n  (下記「Phase 2.5: 4色カラープリント対応」参照)。\n- Phase 3a でマルチビュー入力(正面+背面\u002F左\u002F右)とキャラクターシート自動分割に対応\n  (下記「Phase 3a: マルチビュー入力+キャラクターシート自動分割」参照)。\n- Phase 3b でパラメータプリセット(FR-11)とビューアのオーバーハングヒートマップ\n  (FR-12)に対応(下記「Phase 3b: プリセット+オーバーハングヒートマップ」参照、\n  フロントエンドのみの変更でサーバAPIは不変)。\n- Phase 3c でテクスチャ生成(`texture_mode=paint`、FR-10)に対応(下記\n  「Phase 3c: テクスチャ生成 (texgen)」参照)。custom_rasterizer CUDA拡張の\n  ビルドが必要で、未導入環境では `\u002Fapi\u002Fhealth` の `texgen_available=false` に\n  応じてUI上で無効表示し、正面\u002F背面投影方式(FR-8)にフォールバックする。\n- 3つ目のジェネレータとして **Pixal3D**(MITライセンス、PBRテクスチャ付き出力)を\n  統合(下記「Pixal3Dジェネレータ」参照)。専用venv `.venv-pixal3d` +\n  `IMAGE3D_GENERATOR=pixal3d` の明示指定で使用する。\n- Phase 4a+4b で **ぬいぐるみ型紙生成**(FR-13)に対応(下記「Phase 4a+4b:\n  ぬいぐるみ型紙生成」参照)。生成済みジョブのメッシュをパネルに分割し、\n  各パネルを平坦化(LSCM+ARAP)した上で、縫い代・合印(ノッチ)・布目線付きの\n  実寸SVG型紙をダウンロードできる。\n\n## セットアップ\n\n### 前提\n\n- Python 3.12\n- (Phase 2用) NVIDIA GPU + CUDA 12.8 対応ドライバ\n\n### VRAM最小要件(実測ベース)\n\nRTX PRO 6000 Blackwell 96GB での実測ピーク(既定パラメータ:\n`octree_resolution=384`, `max_faces=200000`, テクスチャ2048×2048)に基づく目安。\n\n| 使用機能 | 実測ピーク | 最小要件 | 備考 |\n|---|---|---|---|\n| mockジェネレータのみ | — | GPU不要 | 開発・UI確認用 |\n| 形状生成(単一ビュー\u002Fマルチビュー) | 約12GB | **16GB** | 単一ビュー・mvの両パイプライン常駐+生成中ピークを含む |\n| +テクスチャ生成 (`texture_mode=paint`) | 約25GB | **32GB** | shape+paint(delight・multiview diffusion)常駐+生成中ピーク |\n\n- `octree_resolution=512` や `max_faces` 増(高精細プリセット)ではピークが上記より\n  増加する。VRAMが最小要件付近のGPUでは `octree_resolution=256` への引き下げを推奨。\n- 生成ジョブは直列実行(NFR-2)のため、同時実行によるVRAM加算は発生しない。\n  各ジョブ後に `torch.cuda.empty_cache()` で解放される(NFR-3で重みは常駐)。\n- 他プロセスとGPUを共有する場合は、上記に加えてそのプロセスの使用量を確保すること。\n\n### venv作成 + 依存インストール\n\nLinux \u002F macOS \u002F WSL2:\n\n```bash\npython3 -m venv .venv\n.venv\u002Fbin\u002Fpip install --upgrade pip\n.venv\u002Fbin\u002Fpip install -r requirements.txt\n```\n\nWindows PowerShell:\n\n```powershell\npy -3.12 -m venv .venv\n.\\.venv\\Scripts\\python.exe -m pip install --upgrade pip\n.\\.venv\\Scripts\\pip.exe install -r requirements.txt\n```\n\nWindowsネイティブでは **Phase 1(mockジェネレータ \u002F CPU)** の利用を想定する。\nHunyuan3D-2 \u002F CUDA \u002F texgen の実モデル生成は、依存関係やCUDA拡張ビルドの都合で\nWSL2 Ubuntu または Linux 環境を推奨する。\n\n`requirements.txt` は base 依存のみ(FastAPI \u002F trimesh \u002F fast-simplification 等)。\nrembg・torch・hy3dgen 等の重い依存は `requirements-gpu.txt` に分離されており、\nPhase 1(mockジェネレータ)では不要。未導入でもアプリ全体が動作する\n(rembgは `server\u002Fpreprocess.py` で遅延import + 自動スキップ)。\n\n### フロントエンド(Three.js)\n\nThree.js はビルド工程なしで `web\u002Fvendor\u002F` にローカル配置済み\n(`three.module.js` \u002F `OrbitControls.js` \u002F `GLTFLoader.js` \u002F `BufferGeometryUtils.js`)。\n追加のnpmインストールは不要。\n\n## 起動\n\nLinux \u002F macOS \u002F WSL2:\n\n```bash\n.\u002Frun.sh\n```\n\nWindows PowerShell:\n\n```powershell\n.\\run.ps1\n```\n\nPowerShellの実行ポリシーでブロックされる場合は、カレントプロセスのみ許可してから起動する:\n\n```powershell\nSet-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass\n.\\run.ps1\n```\n\nデフォルトで `http:\u002F\u002F127.0.0.1:8000` で待ち受ける。ブラウザで開くとUIが表示される。\n\n環境変数で上書き可能:\n\n```bash\nIMAGE3D_GENERATOR=mock IMAGE3D_HOST=127.0.0.1 IMAGE3D_PORT=8000 .\u002Frun.sh\n```\n\nWindows PowerShellでは `$env:` で指定する:\n\n```powershell\n$env:IMAGE3D_GENERATOR = \"mock\"\n$env:IMAGE3D_HOST = \"127.0.0.1\"\n$env:IMAGE3D_PORT = \"8000\"\n.\\run.ps1\n```\n\n主な環境変数(`server\u002Fconfig.py`):\n\n| 変数 | デフォルト | 説明 |\n|---|---|---|\n| `IMAGE3D_GENERATOR` | `auto` | `auto` \\| `mock` \\| `hunyuan3d` \\| `pixal3d`。`auto` はGPU+hy3dgenが利用可能なら `hunyuan3d`、なければ `mock` に自動解決(`pixal3d` は専用venvでの明示指定のみ。「Pixal3Dジェネレータ」の節を参照) |\n| `IMAGE3D_HOST` | `127.0.0.1` | バインドアドレス |\n| `IMAGE3D_PORT` | `8000` | ポート |\n| `IMAGE3D_MAX_UPLOAD_BYTES` | `20971520`(20MB) | アップロード上限 |\n| `IMAGE3D_DEFAULT_TARGET_HEIGHT_MM` | `100` | 後処理のデフォルト目標高さ |\n| `IMAGE3D_DEFAULT_MAX_FACES` | `200000` | 後処理のデフォルト面数上限 |\n\n### アップロード画像と無関係なテスト形状が生成されるとき\n\nmockジェネレータで動作している(画像を反映しない開発用の固定形状を返す)。\nUIヘッダ右上の「生成エンジン」バッジ、または `GET \u002Fapi\u002Fhealth` の `generator` で\n確認できる。mock時はUI上部に警告バナーも表示される。対処:\n\n1. GPU導入手順(後述のPhase 2節)を完了させる。`IMAGE3D_GENERATOR` 未指定\n   (= `auto`)なら、GPU+hy3dgenが使える環境では自動的に `hunyuan3d` が選ばれる。\n2. autoでmockになってしまう場合は `IMAGE3D_GENERATOR=hunyuan3d .\u002Frun.sh` で\n   明示起動し、起動ログのエラー(torch\u002Fhy3dgen未導入、CUDA不可等)を確認する。\n\n## API例\n\n```bash\n# ジョブ作成\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs \\\n  -F \"image=@sample.png\" \\\n  -F 'params={\"target_height_mm\":100,\"seed\":42}'\n# => {\"job_id\": \"...\"}\n\n# 状態確認(ポーリング)\ncurl -s http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\n\n# ビューア用GLB取得\ncurl -s http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fmodel.glb -o model.glb\n\n# STLダウンロード\ncurl -s \"http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fdownload?format=stl\" -o model.stl\n\n# ジョブ一覧 \u002F 削除 \u002F ヘルスチェック\ncurl -s http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\ncurl -s -X DELETE http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\ncurl -s http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fhealth\n\n# マルチビュージョブ作成(Phase 3a、FR-9。image_back\u002Fleft\u002Frightは任意)\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs \\\n  -F \"image=@front.png\" \\\n  -F \"image_back=@back.png\" \\\n  -F 'params={\"seed\":42}'\n\n# キャラクターシート分割(Phase 3a、ジョブを作らない同期API)\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fsheet\u002Fsplit -F \"image=@sheet.png\"\n\n# ぬいぐるみ型紙生成(Phase 4a、FR-13。対象ジョブはcompleted必須)\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fpattern \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"n_panels\": 6, \"use_colors\": true}'\ncurl -s http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fpattern.json\ncurl -s http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fpattern_preview.glb -o pattern_preview.glb\n```\n\n全エンドポイントは [`docs\u002FSPEC.md`](docs\u002FSPEC.md) §5 を参照。\n\n## テスト\n\n```bash\n.venv\u002Fbin\u002Fpytest tests\u002F -v\n```\n\n- `tests\u002Ftest_meshproc.py`: 意図的に穴を開けたメッシュ・浮遊小部品を含むメッシュに対する\n  watertight化・スケーリング・面数上限の検証。\n- `tests\u002Ftest_api.py`: mockジェネレータでジョブのライフサイクル全体\n  (作成→ポーリング→completed→GLB\u002FSTL\u002F3MF\u002FOBJ取得→削除)、および不正入力(非画像ファイル・\n  巨大サイズ・不正JSON・不正パラメータ・不正なcolor_mode\u002Fn_colors)の4xx応答を検証。\n  STL出力はtrimeshで再読込しwatertight・高さ(mm)を機械検証する。カラーモード\n  (`color_mode=color4`)のE2Eテストも含む(stats.palette・3MFマルチオブジェクト・\n  GLB頂点カラーの検証)。\n- `tests\u002Ftest_colorproc.py`: 合成4色ブロック画像+単純メッシュで、頂点カラー投影・\n  k-means量子化(パレット数がn_colors以下)・色ごとの分割(面数合計が元メッシュと\n  一致)・パレット統計(face_ratio合計≈1.0)を検証。\n- `tests\u002Ftest_sheet.py`: 合成RGBAシート画像(透明背景に離れた色付きシルエット3つ)で\n  パネル自動検出(面積フィルタ・近接マージ・左→右ソート)とsuggested_view推定を\n  rembgに依存せず決定的に検証。\n- `tests\u002Ftest_api.py`(Phase 3a追加分): mockで `image` + `image_back` の2ビュー\n  ジョブがcompletedし、`views` フィールドが正しく記録されること、および\n  `POST \u002Fapi\u002Fsheet\u002Fsplit` が合成シート画像から3パネルを検出することを検証。\n- `tests\u002Ftest_texture.py`(Phase 3c追加): GPU不要の純関数\n  `texture.sample_vertex_colors_from_texture` を、合成UV平面メッシュ+\n  既知の4色ブロックテクスチャでUV→ピクセル対応を検証。`texture.is_available()`\n  がbool型を返すことも検証。\n- `tests\u002Ftest_api.py`(Phase 3c追加分): `texture_mode` の不正値が400になること、\n  `\u002Fapi\u002Fhealth` に `texgen_available` が含まれること、mock環境で\n  `texture_mode=paint`(単体・`color_mode=color4`併用)を指定してもジョブが\n  正常completedすること(paint失敗→フォールバック経路を`_run_paint`の\n  モンキーパッチで検証。実際のpaint成功経路はGPU実機検証でカバー)。\n- `tests\u002Ftest_pattern_segment.py`(Phase 4a追加): `server\u002Fpattern\u002F` の\n  TestClient不要の純粋関数テスト。icosphere・カプセルで全面被覆・パネル数・\n  各パネルの連結性・円盤位相(境界ループ1本)・面積合計の整合を検証。\n  上半球赤\u002F下半球青に着色した球で、色境界誘導(`use_colors=True`)が\n  誘導なしと比べ明確にパネル境界を色境界へ寄せることを検証\n  (境界エッジの色差整合率で比較)。`prepare_mesh`\u002F`build_preview_mesh`の\n  基本性質も検証。\n- `tests\u002Ftest_pattern_api.py`(Phase 4a追加、4bで拡張): mockジェネレータで\n  ジョブ作成→ `POST \u002Fapi\u002Fjobs\u002F{id}\u002Fpattern` →\n  `pattern.json`\u002F`pattern_preview.glb`\u002F`pattern.svg`取得をE2E検証(GLBはtrimeshで\n  再読込可能、SVGはXMLパース可能なことも確認)。未完了ジョブへのリクエストが409、\n  `n_panels`\u002F`smooth_iterations`\u002F`seam_allowance_mm` の範囲外が400になることを検証。\n- `tests\u002Ftest_pattern_flatten.py`(Phase 4b追加): `server\u002Fpattern\u002Fflatten.py` の\n  純粋関数テスト。円筒側面(切り開いた円盤位相メッシュ、UV既知)を平坦化し、\n  展開後の高さ・周長が解析解と1%未満の誤差で一致することを検証。平面メッシュは\n  歪みほぼゼロ、半球は歪みが出るが妥当な範囲であることを検証。ARAP反復が\n  LSCM単独より辺長歪みを改善すること、円盤位相でない・空・非連結パネルが\n  例外を投げず`flatten_failed: true`を返すことも検証。\n- `tests\u002Ftest_pattern_svg.py`(Phase 4b追加): `server\u002Fpattern\u002Fsvg.py` の\n  純粋関数テスト。`xml.etree.ElementTree`(標準ライブラリ、テスト側のみで使用)で\n  SVGをパースし、viewBoxがmm実寸であること、パネル数分のグループが存在すること、\n  縫い代パス(オフセットポリゴン)が本体パスより外側(面積が大きい)であること、\n  シームごとの合印が両パネルに同数(偶数個)存在すること、`_detect_seams`が\n  面の双対グラフから求めた真のパネル隣接ペアと一致することを検証。\n\n## Phase 2: GPU導入手順(Hunyuan3D-2、実機検証済み)\n\nRTX PRO 6000 Blackwell (sm_120) 上で動作確認済みの手順。\n\n1. CUDA 12.8対応ドライバのマシンで、cu128ビルドのtorch\u002Ftorchvisionを導入\n   (Blackwellはcu128以降が必須。実機検証時のバージョン: torch 2.11.0+cu128 \u002F\n   torchvision 0.26.0+cu128):\n   ```bash\n   .venv\u002Fbin\u002Fpip install --index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu128 torch torchvision\n   ```\n   確認:\n   ```bash\n   .venv\u002Fbin\u002Fpython -c \"import torch; print(torch.cuda.get_device_name(0), torch.cuda.is_available())\"\n   ```\n\n2. Hunyuan3D-2 (hy3dgen) をソースからcloneし、`--no-deps` でeditableインストール\n   (setup.pyのinstall_requiresにはtexgen\u002Fデモ用途の重い依存(gradio, xatlas,\n   pygltflib, ninja, pybind11等)が含まれ、shapeパイプラインのみの利用では\n   不要なため、依存は個別に導入する):\n   ```bash\n   git clone https:\u002F\u002Fgithub.com\u002FTencent\u002FHunyuan3D-2 third_party\u002FHunyuan3D-2\n   .venv\u002Fbin\u002Fpip install -e third_party\u002FHunyuan3D-2 --no-deps\n   .venv\u002Fbin\u002Fpip install -r requirements-gpu.txt\n   ```\n   `requirements-gpu.txt` には diffusers \u002F transformers \u002F einops \u002F omegaconf \u002F\n   accelerate \u002F opencv-python-headless \u002F scikit-image \u002F pymeshlab (shapeパイプ\n   ラインのpostprocessorsが依存) と rembg \u002F onnxruntime(CPU版)が含まれる。\n\n   注意: rembg\u002Fhy3dgen系の依存解決により numpy が 2.x系に上がる\n   (`requirements.txt` は `numpy\u003C3.0` に緩和済み。trimesh \u002F fast-simplification \u002F\n   meshproc は numpy 2.x でも問題なく動作することを確認済み)。\n\n3. ジェネレータを切り替えて起動:\n   ```bash\n   IMAGE3D_GENERATOR=hunyuan3d .\u002Frun.sh\n   ```\n   初回生成リクエスト時にモデルがHuggingFaceの `tencent\u002FHunyuan3D-2` リポジトリ\n   (`hunyuan3d-dit-v2-0` サブフォルダ、標準shapeモデル、約9.2GB)から\n   `~\u002F.cache\u002Fhuggingface` にダウンロードされ、以降はプロセスに常駐する\n   (`server\u002Fgenerators\u002Fhunyuan3d.py`、NFR-3)。\n\n4. 実画像での実測結果(テスト画像: ぬいぐるみのフィギュア写真、640x960、\n   `IMAGE3D_GENERATOR=hunyuan3d`、steps=30, octree_resolution=384、RTX PRO 6000\n   Blackwell、他プロセスがVRAM約30GB使用中の状態で計測):\n   - パイプラインロード時間(初回): 約15秒\n   - 生成時間(ロード後、diffusion + volume decoding): 約13秒\n   - ジョブ全体(前処理〜後処理〜completed): 約31秒(NFR-1の60秒以内を達成)\n   - VRAMピーク: 約36.6GB(他プロセス分含む。Hunyuan3D-2自体の純増分は約7GB)\n   - 生成メッシュ(後処理前): 386,134頂点 \u002F 772,232面、non-watertight\n   - 後処理後(meshproc、max_faces=200,000、target_height_mm=100):\n     99,998頂点 \u002F 200,000面、**watertight**、高さ 100.01mm\n\n5. 環境変数(`server\u002Fconfig.py`、必要な場合のみ上書き):\n\n   | 変数 | デフォルト | 説明 |\n   |---|---|---|\n   | `IMAGE3D_HY3DGEN_MODEL_PATH` | `tencent\u002FHunyuan3D-2` | HuggingFaceリポジトリID |\n   | `IMAGE3D_HY3DGEN_SUBFOLDER` | `hunyuan3d-dit-v2-0` | 使用するshapeモデルのサブフォルダ(mini版に切替可) |\n   | `IMAGE3D_HY3DGEN_MODELS_DIR` | (hy3dgen既定の`~\u002F.cache\u002Fhy3dgen`) | hy3dgenのローカルモデルキャッシュ探索先 |\n\n## Phase 2.5: 4色カラープリント対応 (FR-8)\n\nBambu Lab AMS、Prusa MMU等のマルチフィラメント方式カラー3Dプリンタ(最大4色)\n向けの出力に対応する。テクスチャ生成AIは使わず、入力画像(背景除去後)を\nメッシュ正面から直交投影して頂点カラーを取得し、k-meansで2〜4色に量子化する\n簡易方式(`server\u002Fcolorproc.py`)。正面画像は正面側の頂点にのみ投影し、追加ビューに\n背面画像がある場合は背面側へ背面画像を投影する。背面画像が無い場合、背面側と\n側面\u002F上下の曖昧な頂点はベース色になる。\n\n### 使い方\n\n1. パラメータフォームの「カラーモード(4色プリンタ向け)」にチェックを入れる。\n2. 「色数 (n_colors)」で2〜4を選択(デフォルト4)。\n3. 生成後、モデル情報バーに量子化されたパレット(色チップ■+面数比率%)が表示される。\n4. ビューアには頂点カラー付きモデルが表示される(GLBに`COLOR_0`属性として出力、\n   three.jsのGLTFLoaderが自動で頂点カラー表示する)。\n5. エクスポートの「3MF」ボタンでダウンロードすると、通常の単色3MFではなく\n   **色ごとに分割された最大4オブジェクト**(名前 `color_1`〜`color_4`、\n   表示色付き)を含む3MFが得られる。STL\u002FOBJ\u002F通常想定の単一3MFは従来通り\n   形状のみ(色情報なし)。\n\nAPIパラメータ: `params` JSONに `color_mode`(`\"none\"` | `\"color4\"`)と\n`n_colors`(2〜4、デフォルト4)を指定する。\n\n```bash\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs \\\n  -F \"image=@sample.png\" \\\n  -F 'params={\"color_mode\":\"color4\",\"n_colors\":4,\"seed\":42}'\n\n# 3MF(カラーモード時は色ごとに分割されたマルチオブジェクト版)\ncurl -s \"http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fdownload?format=3mf\" -o model_color.3mf\n```\n\nジョブ完了時の `stats.palette` にHEXカラーと面数比率が入る:\n\n```json\n\"palette\": [\n  {\"hex\": \"#090512\", \"face_ratio\": 0.356},\n  {\"hex\": \"#f0e1cc\", \"face_ratio\": 0.249},\n  {\"hex\": \"#b17f7a\", \"face_ratio\": 0.230},\n  {\"hex\": \"#753444\", \"face_ratio\": 0.166}\n]\n```\n\n### スライサーでのフィラメント割当手順(概説)\n\n1. 上記3MFファイル(`model_color.3mf`相当、ダウンロード時のファイル名は\n   `\u003Cjob_id>_color.3mf`)をBambu Studio \u002F PrusaSlicerなど対応スライサーで開く。\n2. 3MF内には最大4個のオブジェクト(`color_1`〜`color_4`)が別々のパーツとして\n   読み込まれる。各オブジェクトはモデル情報バーのパレット表示・\n   `stats.palette`のHEXに対応する色でエクスポートされている。\n3. スライサーのオブジェクト\u002Fパーツ一覧から各 `color_N` を選択し、\n   対応するAMS\u002FMMUスロットのフィラメント色を割り当てる\n   (パレットのHEXに近い色のフィラメントを選ぶと元画像の配色に近くなる)。\n4. 通常のマルチカラー印刷設定(パージタワー・ウォッシングタワー等)で\n   スライスする。\n\n### 実機検証結果 (GPU, momo.png)\n\n`IMAGE3D_GENERATOR=hunyuan3d`、`color_mode=color4`, `n_colors=4`, `seed=42`、\n入力画像 `momo.png`(640x960、ぬいぐるみ写真)で検証:\n\n- ジョブ完了時間: 約34秒\n- `stats.palette`: 4色(黒系・生成りの毛色・肌色系・臙脂色の4クラスタ)、\n  face_ratio合計 ≈ 1.0\n- 3MFダウンロード → trimeshで再読込 → ジオメトリ数4(`color_1`〜`color_4`、\n  面数合計200,000 = 単色出力時と同一)\n- GLBに`COLOR_0`頂点カラー属性が含まれ、three.jsビューアで色表示を確認\n- **左右ミラー検証**: 入力画像は非対称な特徴(右耳の黒い内側パネル)を持つため、\n  生成メッシュの頂点カラーをメッシュ正面(-Y向き)から直交投影して可視化し、\n  画像の右側にある黒いパネルがメッシュの+X側(画像を正面から見て右側)に\n  正しく再現されることを確認した。`server\u002Fcolorproc.py`の`_U_TO_X_SIGN=+1`\n  (画像u=0が-X側、u=1が+X側)がこの実機検証で確定した値である。\n\n## Phase 3a: マルチビュー入力+キャラクターシート自動分割 (FR-9)\n\n複数ビュー画像(正面必須+背面\u002F左側面\u002F右側面の任意組合せ)から3Dモデルを生成できる。\n複数ビュー時は Hunyuan3D-2 のマルチビューモデル `hunyuan3d-dit-v2-mv`\n(リポジトリ `tencent\u002FHunyuan3D-2mv`。単一ビュー用の `tencent\u002FHunyuan3D-2` とは\n別リポジトリである点に注意)を使用する。単一画像時は従来通り\n`hunyuan3d-dit-v2-0` を使用する。両パイプラインは別インスタンスとして\n共存常駐する(`server\u002Fgenerators\u002Fhunyuan3d.py`)。\n\nまた、1枚のキャラクターシート画像(複数ビューが並んだ画像)から被写体パネルを\n自動検出し、各パネルをUI上で正面\u002F背面\u002F左\u002F右のいずれかに割り当てて生成に\n使用できる(`server\u002Fsheet.py`)。\n\n### 使い方(マルチビュー生成)\n\n1. 左ペイン「1. 画像アップロード」で正面画像をアップロードする(必須)。\n2. 「追加ビュー(任意)」の背面\u002F左側面\u002F右側面の枠に、対応する画像を\n   ドラッグ&ドロップまたはクリックしてアップロードする(いずれも省略可、\n   個別に「×クリア」で解除可能)。\n3. 追加ビューを1枚以上指定すると、進捗欄付近に「Nビュー(front\u002Fback\u002F...)で\n   生成」という表示が出る。\n4. 「3Dモデルを生成」を押すと、複数ビュー時は自動的にマルチビューパイプライン\n   (`hunyuan3d-dit-v2-mv`)で生成される。\n\nAPIでは `POST \u002Fapi\u002Fjobs` の multipart フィールドとして `image`(正面、必須)に\n加え `image_back` \u002F `image_left` \u002F `image_right`(任意)を送信する:\n\n```bash\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs \\\n  -F \"image=@front.png\" \\\n  -F \"image_back=@back.png\" \\\n  -F 'params={\"seed\":42}'\n```\n\nジョブ完了後、`GET \u002Fapi\u002Fjobs\u002F\u003Cjob_id>` の応答に `views`(例:\n`[\"front\", \"back\"]`)が含まれ、実際にどのビューが使われたかを確認できる。\n各追加ビューにも背景除去(`remove_bg`指定時)が適用される。カラー投影\n(`color_mode=color4`時の頂点カラー、FR-8)は正面(front)画像を正面側に使い、\n背面(back)画像があれば背面側にも使用する。\n\n### 使い方(キャラクターシート自動分割)\n\n1. 左ペイン「キャラクターシート分割(任意)」の「シート画像を選んで分割」を\n   押し、複数ビューが1枚に並んだシート画像を選択する。\n2. `POST \u002Fapi\u002Fsheet\u002Fsplit` が呼ばれ、検出されたパネルがサムネイル一覧として\n   表示される。各パネルには割当セレクト(正面\u002F背面\u002F左\u002F右\u002F使わない)が付き、\n   初期値は左からの並び順ヒューリスティクス(正面→側面→背面の順を仮定)で\n   自動推定される。\n3. 必要に応じて割当を修正し、「この割当を使用」を押すと、各パネル画像が\n   対応するアップロード欄(正面画像・追加ビュー欄)に反映される。\n4. 通常通り生成パラメータを設定して「3Dモデルを生成」を押す。\n\nパネル自動検出のロジック(`server\u002Fsheet.py`):\n\n1. 前景マスク取得: RGBA画像でアルファに情報があればそれを使用。無ければ\n   rembgでマスクを取得。それも不可なら四隅の背景色との色差で2値化する。\n2. マスクの連結成分解析(`scipy.ndimage.label`)。画像全体の1%未満の成分は\n   除去し、間隔が画像幅の2%未満のバウンディングボックス同士はマージする。\n3. 残ったボックスを左→右(同列なら上→下)にソートし、パディング付きで\n   切り出す(最大6パネル)。\n\n`\u002Fapi\u002Fsheet\u002Fsplit` はジョブを作らない同期APIで、数秒で結果を返す:\n\n```bash\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fsheet\u002Fsplit -F \"image=@sheet.png\"\n# => {\"panels\": [{\"index\": 0, \"image_b64\": \"...\", \"suggested_view\": \"front\"}, ...]}\n```\n\n### 実機検証結果 (GPU, momo.png + 左右反転画像)\n\n`IMAGE3D_GENERATOR=hunyuan3d`、front=`momo.png`(640x960)、\nback=momo.pngの左右反転画像、`seed=42`、`color_mode=color4`, `n_colors=4`\nの2ビュージョブで検証(ポート8021、8020の既存プロセスとは別プロセス):\n\n- **mvモデル初回DLサイズ**: 約9.2GB\n  (`tencent\u002FHunyuan3D-2mv`、subfolder `hunyuan3d-dit-v2-mv`、\n  `~\u002F.cache\u002Fhuggingface` に保存。単一ビュー用モデルとは別リポジトリのため\n  重複してDLされる)。\n- **生成時間**:\n  - 初回(モデルDL含む): ジョブ作成から完了まで約135秒\n    (うちDL+ロード+生成が約120秒)。\n  - 2回目以降(モデル常駐後): ジョブ作成から完了まで約22秒\n    (NFR-1の60秒以内を達成)。\n- **生成メッシュ統計**(後処理後、max_faces=200,000、target_height_mm=100):\n  99,972頂点 \u002F 200,000面、non-watertight、高さ 100.00mm、\n  bbox (68.9 x 46.3 x 100.0) mm。\n- **GLB**: 頂点カラー(`COLOR_0`)付きで出力、99,972頂点分のカラーを保持。\n- **3MF**: 色ごとに分割された4オブジェクト、面数合計200,000\n  (単色出力時と一致)。\n- **STL**: 高さ100.00mm、trimeshで再読込可能。\n- 同一サーバプロセス上で単一ビュー用パイプライン(`hunyuan3d-dit-v2-0`)と\n  マルチビュー用パイプライン(`hunyuan3d-dit-v2-mv`)が共存常駐し、\n  それぞれ単一ビュージョブ・複数ビュージョブを問題なく処理できることを確認した\n  (VRAM: 両モデル常駐時で合計使用量 約46GB、他プロセス分約35.7GB含む)。\n\n### キャラクターシート分割の動作確認\n\n合成RGBAシート画像(透明背景に離れた色付きシルエット3つ)と実際のUI操作\n(ブラウザ経由でのcanvas生成シート画像)の両方で、3パネルの検出・\n左→右の順序・suggested_view(front\u002Fleft\u002Fback)の初期推定・パネル画像への\n反映(正面画像プレビュー・追加ビュー欄への自動設定)を確認済み\n(`tests\u002Ftest_sheet.py`、`tests\u002Ftest_api.py`)。\n\n## Phase 3b: プリセット+オーバーハングヒートマップ (FR-11, FR-12)\n\nフロントエンドのみの拡張(サーバAPI変更なし)。`web\u002Findex.html` \u002F `web\u002Fapp.js` \u002F\n`web\u002Fviewer.js` \u002F `web\u002Fstyle.css` を変更。\n\n### プリセット (FR-11)\n\n「2. 生成パラメータ」フォーム最上部にプリセットセレクタを追加。選択すると\n対応するパラメータがフォームに一括反映される。\n\n| プリセット | target_height_mm | octree_resolution | max_faces | カラーモード |\n|---|---|---|---|---|\n| フィギュア | 100 | 384 | 200,000 | 変更なし |\n| 小型フィギュア | 60 | 256 | 100,000 | 変更なし |\n| ペンダント | 40 | 256 | 80,000 | OFFに強制 |\n| 高精細 | 150 | 512 | 400,000 | 変更なし |\n\n先頭の「カスタム」は何も反映しない初期値。プリセット反映後にユーザーが\n`target_height_mm` \u002F `octree_resolution` \u002F `max_faces` \u002F カラーモードの\nいずれかを個別に変更すると、セレクタ表示は自動的に「カスタム」に戻る\n(実装は `web\u002Fapp.js` の `PRESETS` 定義と `change` イベントリスナー)。\n\n### オーバーハングヒートマップ (FR-12)\n\n3Dビューア上部の表示切替に「オーバーハング」ボタンを追加(既存の\nシェーディング\u002Fワイヤーフレームと排他)。クリックすると、表示中メッシュの\n面法線から下向き傾斜角を算出し、頂点色として以下の配色でベイクした\n`MeshBasicMaterial`(照明の影響を受けず頂点色をそのまま表示)に切り替える。\n\n- 接地面付近(モデル高さの下端2%未満): 薄青(サポート不要)。\n- 下向き傾斜角が閾値(既定45°)を超える面: 赤(超過度合いに応じて白→赤の\n  グラデーション)。\n- 閾値以下の面: 白〜薄グレー(傾斜が小さいほど白に近い)。\n\nオーバーハングモード中のみ閾値スライダー(30°〜70°、1°刻み)を表示し、\n変更するとその場でヒートマップを再計算する(サーバ通信なし、\n`Viewer.setOverhangThreshold()`)。\n\n傾斜角は、GLBロード時にワールド座標変換した面法線とワールド下方向\n(`(0, -1, 0)`。ビューアは生成メッシュ(Z-up)をラッパーグループでX軸-90度回転し\nY-upとして表示しているため、シーン内では常にY軸が造形の高さ方向になる)との\nなす角から求める。\n\nシェーディング\u002Fワイヤーフレームに戻すと、退避しておいた元のマテリアルと\n頂点カラー属性(4色プリント時の `COLOR_0` 等)を復元する\n(`Viewer._backupAndApplyOverhang()` \u002F `_restoreOriginalMaterials()`)。\n新しいモデルをロードするとオーバーハングモードは自動的に解除され、\n表示はシェーディングに戻る。\n\n### 動作確認 (mock、ポート8021)\n\n`IMAGE3D_GENERATOR=mock` のサーバ(ポート8021、8020の既存プロセスとは別)で、\n既存の完了済みジョブ(4色カラーのぬいぐるみ形状、99,972頂点\u002F200,000面)を\nビューアにロードし、ブラウザJS経由で以下を確認した(新規ジョブは作成せず、\n既存ジョブの参照のみで検証したためジョブ削除は不要だった)。\n\n- プリセット4種それぞれで `target_height_mm` \u002F `octree_resolution` \u002F\n  `max_faces` がフォームに反映されること、ペンダント選択時にカラーモードが\n  OFFになること、反映後に個別フィールドを変更するとセレクタが「カスタム」に\n  戻ることを確認。\n- オーバーハングボタン押下で頂点カラー属性が書き換わり、閾値45°時に\n  99,972頂点中 赤(オーバーハング)7,883・薄青(接地面)1,723・\n  白〜グレー(安全)90,366(その他0)に分類されることを確認(数値は\n  `geometry.getAttribute(\"color\")` を直接読み出して集計)。\n- 閾値スライダーを30°に下げると赤判定頂点が16,745に増加、70°に上げると\n  ごく一部(股下など急傾斜面のみ)に減ることを確認(閾値と赤面積が単調に\n  連動)。\n- スクリーンショットで赤(オーバーハング: 腕の下側・肩・股下等)\u002F\n  白(安全)\u002F薄青(接地面)の3配色が視認できることを確認。\n- シェーディングボタンに戻すと、頂点カラーが元のパレット値\n  (`[0.553, 0.345, 0.2]` 等)に完全復元され、マテリアルも元のカラー表示に\n  戻ることを確認。\n\n## Phase 3c: テクスチャ生成 (texgen, FR-10)\n\nHunyuan3D-2 の paint パイプライン(`hunyuan3d-paint-v2-0` + `hunyuan3d-delight-v2-0`)\nを用いて、生成メッシュに全周テクスチャ(UV展開 + 2048x2048テクスチャ画像)を\n焼き込む。`texture_mode=paint` を指定した場合のみ実行される(デフォルト `none`)。\n\n### セットアップ(custom_rasterizer CUDA拡張のビルド)\n\ntexgenの内部レンダラ(`hy3dgen\u002Ftexgen\u002Fdifferentiable_renderer`)は\n`custom_rasterizer_kernel` というCUDA拡張(pybind11 + CUDA C++)を要求する。\nこの拡張は Hunyuan3D-2 リポジトリに同梱されているがビルド済みバイナリは\n配布されないため、対象マシンでソースからビルドする必要がある。\n\n**重要な既知の落とし穴**: システムの `nvcc`(`nvcc --version` で確認)と\ntorchのCUDAビルド(`python -c \"import torch; print(torch.version.cuda)\"`)の\n**メジャーバージョンが一致しないとビルドに失敗する**。本プロジェクトの実機は\nシステムCUDAが13.0、torchがcu128(CUDA 12.8)ビルドという不一致環境だったが、\n`\u002Fusr\u002Flocal\u002Fcuda-12.8` に別途CUDA 12.8ツールチェーンが用意されていたため、\n`CUDA_HOME`\u002F`PATH` で明示的にそちらを指定してビルドすることで解決した\n(torchバージョンチェックの回避等は不要だった)。\n\n```bash\n# 1. 追加のPython依存を導入(shapeパイプラインのみの --no-deps 導入では\n#    含まれていないもの。requirements-gpu.txt参照)\n.venv\u002Fbin\u002Fpip install xatlas pybind11 ninja pygltflib\n\n# 2. torchのCUDAビルドと同じメジャーバージョンのCUDAツールチェーンを用意する。\n#    無ければ https:\u002F\u002Fdeveloper.nvidia.com\u002Fcuda-12-8-0-download-archive 等から\n#    該当バージョンのtoolkitのみ(ドライバは不要)を追加インストールする。\nls \u002Fusr\u002Flocal\u002F | grep cuda   # 例: cuda-12.8 が既にあるか確認\n\n# 3. custom_rasterizer をビルド・インストール\ncd third_party\u002FHunyuan3D-2\u002Fhy3dgen\u002Ftexgen\u002Fcustom_rasterizer\nCUDA_HOME=\u002Fusr\u002Flocal\u002Fcuda-12.8 PATH=\"\u002Fusr\u002Flocal\u002Fcuda-12.8\u002Fbin:$PATH\" \\\n  TORCH_CUDA_ARCH_LIST=\"12.0\" \\\n  ..\u002F..\u002F..\u002F..\u002F..\u002F.venv\u002Fbin\u002Fpip install . --no-build-isolation --no-deps\n\n# 4. 動作確認(torchを先にimportしないとlibc10.so等が解決できない点に注意)\n.venv\u002Fbin\u002Fpython -c \"\nimport torch\nimport custom_rasterizer as cr\nprint('OK:', cr.rasterize)\n\"\n```\n\n`TORCH_CUDA_ARCH_LIST` は対象GPUのCompute Capabilityに合わせる\n(RTX PRO 6000 Blackwell \u002F sm_120 の場合は `\"12.0\"`)。\n\n`differentiable_renderer\u002Fmesh_processor`(pybind11拡張、`mesh_processor.cpp`)は\n**ビルド不要**: `mesh_render.py` は `from .mesh_processor import meshVerticeInpaint`\nというパッケージ内相対importで読み込むため、同ディレクトリの純Python実装\n(`mesh_processor.py`)がPythonのimport解決で優先され、コンパイル済み拡張が\n無くても動作する。\n\n**既知の追加修正(vendored コードのパッチ)**: 導入したdiffusersのバージョン\n(0.39.0)では、ローカルの `custom_pipeline`(`hy3dgen\u002Ftexgen\u002Fhunyuanpaint\u002F`)を\n`DiffusionPipeline.from_pretrained(..., custom_pipeline=...)` でロードする際に\n`trust_remote_code=True` を明示しないと `ValueError` になる仕様変更が入っている。\n`third_party\u002FHunyuan3D-2\u002Fhy3dgen\u002Ftexgen\u002Futils\u002Fmultiview_utils.py` の\n`DiffusionPipeline.from_pretrained(...)` 呼び出しに `trust_remote_code=True` を\n追加するパッチを適用済み(このリポジトリに同梱された既知のコードを読み込む\nだけなので安全)。third_party を作り直す場合は同様のパッチが必要になる。\n\n### 可用性チェックとフォールバック(3c-3)\n\n`server\u002Ftexture.py` の `is_available()` が、依存import(`custom_rasterizer_kernel`,\n`hy3dgen.texgen.Hunyuan3DPaintPipeline`)とGPU有無を実ロードせずに確認し、\n`GET \u002Fapi\u002Fhealth` の `texgen_available` に反映する。ビルド未実施・GPU無し環境\nでは `false` になり、UIの「テクスチャ生成(実験的)」チェックボックスが\n無効化され「この環境では利用できません」と表示される(サーバAPI自体は\n`texture_mode=paint` を引き続き受け付けるが、実行時にpaintが失敗した場合と\n同様にgracefulにフォールバックする)。\n\npaint実行が失敗した場合(モデル未DL・OOM・その他例外)もジョブは `failed` に\nせず、`meta.json` の `warnings` に日本語メッセージを記録した上で、従来の\n正面\u002F背面投影方式(FR-8、`colorproc.project_multiview_colors`)による `color_mode=color4`\n処理を続行する。ジョブJSONの `textured` フィールドで実際にpaintが成功したか\nどうかを判定できる(`true`=テクスチャ付きGLB、`false`=フォールバック)。\n\n### 使い方\n\n1. `\u002Fapi\u002Fhealth` で `texgen_available: true` であることを確認(UIでは\n   チェックボックスが有効表示されていれば利用可能)。\n2. パラメータフォームの「テクスチャ生成(実験的)」にチェックを入れて生成する。\n3. 完了後、ビューア用GLB(`GET \u002Fapi\u002Fjobs\u002F\u003Cjob_id>\u002Fmodel.glb`)にテクスチャ\n   (2048x2048 PNG、`baseColorTexture`)付きのPBRマテリアルが焼き込まれる。\n   STL\u002FOBJ\u002F通常3MFは従来通り形状のみ。\n4. `color_mode=color4` と併用した場合、頂点カラーの取得元が\n   「入力画像の正面投影」から「焼き込まれたテクスチャをUV経由でサンプリング」\n   (`server\u002Ftexture.py: sample_vertex_colors_from_texture`)に切り替わり、\n   全周の実際の配色に基づいた4色3MFが生成される(側面・背面の色も反映される\n   ため、FR-8単体運用時より配色精度が上がる)。\n\n```bash\ncurl -s -X POST http:\u002F\u002F127.0.0.1:8000\u002Fapi\u002Fjobs \\\n  -F \"image=@sample.png\" \\\n  -F 'params={\"texture_mode\":\"paint\",\"color_mode\":\"color4\",\"n_colors\":4,\"seed\":42}'\n```\n\n### 実機検証結果 (GPU, momo.png, ポート8021)\n\n`IMAGE3D_GENERATOR=hunyuan3d`、`texture_mode=paint`、`color_mode=color4`、\n`n_colors=4`、`seed=42`、入力画像 `momo.png` で検証(検証後ジョブは削除済み):\n\n- custom_rasterizer のビルド: `\u002Fusr\u002Flocal\u002Fcuda-12.8` を明示指定して**1回目の\n  試行で成功**(torchバージョンチェック回避等のハック不要)。\n- paintパイプライン初回実行: `hunyuan3d-paint-v2-0` + `hunyuan3d-delight-v2-0`\n  のHuggingFaceからの初回ダウンロードを含めて完了(ジョブ全体で約104秒)。\n- 2回目以降(モデル常駐後): ジョブ全体で約80〜100秒(shape生成 + 後処理 +\n  paint)。\n- 生成GLBの検証: glTF JSONを直接パースし、`materials[0].pbrMetallicRoughness\n  .baseColorTexture` が存在し `images[0]` (PNG, 2048x2048) を参照、\n  `meshes[0].primitives[0].attributes` に `TEXCOORD_0` が含まれることを確認。\n  trimeshでの再読込でも `visual.kind == \"texture\"` かつ\n  `material.baseColorTexture.size == (2048, 2048)` を確認した。\n- 3MFダウンロードのジオメトリ数: 4(`color_1`〜`color_4`)。\n- `job[\"textured\"]` が `true`、`job[\"warnings\"]` が空であることを確認。\n- VRAMピーク: 約54.4GB(shapeパイプライン + paintパイプライン + delightモデル\n  すべて常駐した状態。NFR上の96GB VRAM予算内)。\n- `texture_mode=paint` かつ `color_mode=none` の組合せでも同様にテクスチャ付き\n  GLBが生成されることを確認。\n- 検証用サーバ(ポート8021)は検証後に停止し、テストジョブは全て削除した。\n\n### 既知の制限(texgen固有)\n\n- custom_rasterizer のビルドには、torchのCUDAビルドとメジャーバージョンが\n  一致するCUDAツールチェーンが別途必要(システムのnvccと不一致な場合)。\n  ビルド環境が用意できない場合は `texgen_available=false` となり自動的に\n  フォールバックする(アプリ自体は壊れない)。\n- paintパイプラインはCPU実行を想定していない(`Hunyuan3DTexGenConfig` が\n  `device='cuda'` 固定)。GPU無し環境では `is_available()` が常に `false` を\n  返す。\n- paint処理は shape生成用パイプラインとは別にVRAMを消費する(delight +\n  multiview拡散 + 内部レンダラ)。直列キュー(NFR-2)により同時実行は防がれる\n  が、`target_height_mm`\u002F`max_faces` を大きくした高解像度メッシュではVRAM\n  使用量が増える点に注意。\n- paint後のテクスチャは全周を6視点(正面\u002F背面\u002F左右\u002F上\u002F下相当)からの\n  マルチビュー拡散結果をベイクする方式のため、細部の一貫性は入力画像の\n  品質・被写体の複雑さに依存する。\n- **目など小さく高コントラストな特徴のズレ・シームは既知の限界**:\n  正面画像は参照にのみ使われ、他の5ビューは `Hunyuan3DPaintPipeline`\n  (`third_party\u002FHunyuan3D-2\u002Fhy3dgen\u002Ftexgen\u002Fpipelines.py`)がマルチビュー\n  拡散モデルで新規生成する。生成ビュー間で目の位置が完全には一致せず、\n  それをメッシュへベイクする際にズレ・二重写り・輪郭のシームとして\n  現れることがある。彫りの浅い(平坦に近い)ジオメトリのぬいぐるみ系被写体\n  で特に目立ちやすい。`__call__(self, mesh, image)` にsteps\u002F解像度等の\n  品質調整パラメータは公開されておらず、アプリ側からのチューニング余地は\n  無い。正面の色精度を優先したい場合は `texture_mode=none` にして\n  従来の正面\u002F背面投影(`colorproc.project_multiview_colors`)を使う方が\n  ズレは出ないが、360°の質感は失われ側面が単色寄りになるトレードオフがある。\n- `hy3dgen\u002Ftexgen\u002Futils\u002Fmultiview_utils.py` に `trust_remote_code=True` を\n  追加するパッチが必要(上記セットアップ参照)。third_party ディレクトリを\n  再取得(git clone)した場合は再適用が必要。\n\n## Phase 4a+4b: ぬいぐるみ型紙生成\n\n生成済みジョブのメッシュから、ぬいぐるみ縫製用の型紙(SPEC.md §3.12 \u002F FR-13)を\n生成する。Phase 4aで**パネル分割+3Dプレビュー**、Phase 4bで**平坦化\n(LSCM+ARAP)+実寸SVG出力**(縫い代・合印・布目線付き)を実装済み。\n\n### モジュール設計\n\n`server\u002Fpattern\u002F` は将来の独立リポジトリ化に備えた**純粋モジュール**\n(`server\u002FDEVELOPMENT_POLICY.md` §3.5)。`server\u002F` 内の他モジュール\n(config・jobs・generators・colorprocなど)を一切importせず、依存は\nnumpy \u002F scipy \u002F trimesh のみ(新規pip依存の追加なし)。\n\n- `server\u002Fpattern\u002Fpreprocess.py`: `prepare_mesh()` — Taubin平滑化\n  (失敗時はラプラシアンにフォールバック)→ 簡略化(1万〜2万面。\n  `fast-simplification` は既存の `requirements.txt` 依存を流用、\n  失敗時は trimesh標準の `simplify_quadric_decimation` にフォールバック)\n  → 最大連結成分抽出。頂点カラーがあれば最近傍で新メッシュへ転写する。\n- `server\u002Fpattern\u002Fsegment.py`: `segment_panels()` — 面の双対グラフ上で\n  farthest-point samplingによりシード面を選び、エッジ重み付き多始点\n  最短路(`scipy.sparse.csgraph.dijkstra`)でVoronoi風にパネルを成長させる。\n  凹エッジ(谷折れ)・色境界(`use_colors=True`時)のエッジは**通行コストを\n  上げる**ことでパネル境界がそこに沿いやすくなるよう誘導する\n  (直感に反して「軽くする」方向では逆効果になることを実験で確認済み。\n  詳細はモジュール内docstring参照)。後処理で (a) 非連結パネルの最寄り\n  パネルへの再割当、(b) 極小パネル(全面積2%未満)の隣接吸収、\n  (c) 円盤位相(境界ループ1本)の判定・修復を行う。修復しきれない場合は\n  例外にせず `panel_stats()` の `disk_topology: false` に正直に反映する。\n- `server\u002Fpattern\u002Fpreview.py`: `build_preview_mesh()` — パネルごとに\n  隣接パネルが似た色にならない固定12色パレットで面カラーを塗ったメッシュを返す。\n- `server\u002Fpattern\u002Fflatten.py`(Phase 4b): `flatten_panel(mesh, face_indices)` —\n  円盤位相のパネル(部分メッシュ)を2Dへ展開する。\n  1. **LSCM初期解**(least squares conformal map): 各三角形を法線に直交する\n     局所2D等長座標系へ写し、コーシー・リーマン残差を最小二乗(`scipy.sparse.linalg.lsqr`)\n     で解く。固定する2頂点は、メッシュ上で実際に隣接する**最長エッジの両端**を選ぶ\n     (バウンディングボックス対角の任意2点を選ぶと、直線距離と測地距離の乖離から\n     大きなシェア(せん断)が生じ、後段のARAPでも解消できないことを実験で確認し、\n     この選び方に変更した)。\n  2. **ARAP反復**(as-rigid-as-possible、5〜15回): 三角形ごとに3D→2Dの最適回転を\n     2x2 SVDで求める局所ステップと、コットジェント重み付きラプラシアン系\n     (`scipy.sparse.linalg.spsolve`)を解く大域ステップを交互に反復し、辺長歪みを\n     低減する。大域ステップのRHSは三角形ごとの**半コットジェント**(この三角形単独の\n     寄与)を使う(大域行列の対称重み=両側三角形の和をそのままRHSにも使うと\n     二重計上になり発散することを実装時に確認・修正した)。\n  歪み指標(辺長歪みの最大・最小・平均・±10%超の割合、2D\u002F3D面積比)を返す。\n  円盤位相でないパネルは例外にせず `{\"flatten_failed\": True, \"reason\": ...}` を返し、\n  他パネルの処理を継続できるようにする。\n- `server\u002Fpattern\u002Fsvg.py`(Phase 4b): `build_pattern_svg(panels_2d, seam_allowance_mm, ...)` —\n  平坦化済みパネルから実寸(mm単位viewBox)SVG型紙を組み立てる。パネルは単純な\n  シェルフ法で矩形パッキング。縫い代線は境界ポリゴンの頂点法線方向オフセット\n  (マイタ近似+短エッジ間引きによる簡易クリーンアップ)。合印(ノッチ)は、\n  パネル境界の3D座標を突き合わせて隣接パネル間のシーム(共有境界)を検出し、\n  シームごとに2〜4個、対応する2パネルの両側に同一シームIDを付けて配置する。\n  パネル番号ラベル・布目線(縦の両矢印)・凡例(モデル名・高さ・縫い代・\n  シーム対応表)も含む。XMLライブラリには依存せず文字列組み立てで生成する。\n\n### API・UI\n\n- `POST \u002Fapi\u002Fjobs\u002F{id}\u002Fpattern`(body: `n_panels`(4〜12, 既定6)、\n  `use_colors`(既定true)、`smooth_iterations`(既定10)、`seam_allowance_mm`\n  (1〜30, 既定7)) → 同期実行(数秒)で `pattern.json`(実パネル数・パネルごとの\n  面数\u002F面積\u002F円盤位相\u002F平坦化歪み指標)、`pattern_preview.glb`(パネル色分けメッシュ)、\n  `pattern.svg`(実寸型紙)をジョブディレクトリへ保存。対象ジョブが `completed`\n  でなければ409、パラメータ範囲外は400。\n- `GET \u002Fapi\u002Fjobs\u002F{id}\u002Fpattern.json` \u002F `pattern_preview.glb` \u002F `pattern.svg`\n  で取得(未生成時404、`pattern.svg` は `image\u002Fsvg+xml`)。\n- UI: ビューア下部に「ぬいぐるみ型紙を生成」ボタン。クリックでパネル数・\n  縫い代(mm)スライダ、色境界誘導チェックボックスを表示。実行するとビューアに\n  パネル色分けプレビューが表示され(「モデル表示に戻す」で通常表示に戻せる)、\n  パネルごとの辺長歪み(±10%超の割合、閾値超は警告色)、「型紙SVGをダウンロード」\n  ボタン、SVGのインラインプレビュー(`\u003Cdetails>`内`\u003Cimg>`)が表示される。\n\n### 実メッシュでの検証結果\n\nmockジェネレータ(`IMAGE3D_GENERATOR=mock`)でAPI・UIのE2E動作を確認した上で、\n実際に生成済みの `data\u002Fjobs\u002F` 内メッシュに対して直接 `server\u002Fpattern\u002F` を\n実行して検証した。\n\n- **hunyuan3d生成メッシュ(momo.png、頂点カラーなし)**: 3ジョブ ×\n  パネル数 4\u002F6\u002F8\u002F10\u002F12 の計15ケースで **disk_topology達成率 89.8%\n  (106\u002F118パネル)**。パネル数を増やすほど個々のパネルが小さくなり\n  円盤位相を保ちやすくなる傾向(n_panels=10, 12では概ね90%超〜100%)。\n  処理時間は前処理+分割で1ジョブあたり1秒未満。\n- **pixal3d生成メッシュ(momo.png、頂点カラー付き、ジョブ`58d8e1d0`)**:\n  色境界誘導は機能する(球のような単純形状でのテストでは境界エッジの\n  色差整合率が誘導なしの2〜9%から63〜85%まで改善することを単体テストで\n  確認済み)一方、このジョブの実メッシュでは **disk_topology達成率が\n  0\u002F5** と低かった。原因を調査したところ、`model.glb` 自体が\n  `merge_vertices()` 後も440個の連結成分・940本の非多様体エッジ\n  (3面以上を共有するエッジ)を含む、UVアトラス起因の位相的に汚れた\n  メッシュであることが判明した(パネル分割アルゴリズム側の不具合ではなく、\n  Pixal3D側のGLB化パイプラインに起因する既知の制約。関連: 本READMEの\n  「Pixal3Dジェネレータ」節、`server\u002Fgenerators\u002Fpixal3d_raster.py`)。\n  `prepare_mesh()` の平滑化・簡略化・最大連結成分抽出はこの種の非多様体\n  性を完全には解消できないため、円盤位相修復に失敗したパネルは\n  `disk_topology: false` として正直に報告される(仕様通りの挙動)。\n\n**Phase 4b(平坦化+SVG)の解析解検証**: 円筒側面(高さ40mm・半径8mm相当、\nUVパラメータ化が既知)を1本の縦シームで切り開いたメッシュを`flatten_panel()`で\n展開し、展開後の高さ・周長が3D解析解と一致するかを検証した。\n\n- 高さ誤差 **約0.0000012%**、周長誤差 **約0.29%**(いずれも目標の1%未満)。\n- ARAP反復による改善: 半球パネル(非可展)でLSCM単独(0回反復)は辺長歪み\n  ±10%超の割合96.6%・面積比0.36(3D比)だったのに対し、ARAP12回反復後は\n  ±10%超48.4%・面積比0.96まで改善。ARAP反復が確かに歪みを低減することを確認。\n\n**Phase 4b の実データ検証(momo.png、hunyuan3dジョブ、mockサーバ:8021)**:\n既存ジョブ `02edf6c8-b1e2-4267-9306-dd5bb387794a`(頂点カラー付き、\nモデル寸法 67.8×45.1×100.0mm)に対し `n_panels=8, seam_allowance_mm=7` で\n`POST \u002Fpattern` → `pattern.svg` を取得して検証した。\n\n- disk_topology 8\u002F8、flatten成功 8\u002F8(全パネル平坦化成功)。\n- SVG: `viewBox`・`width`\u002F`height` ともmm実寸(全体 767.5mm×156.0mm、\n  8パネルをシェルフパッキング)。個々のパネルの実寸bboxは約40×38mm〜\n  84×74mm(100mmモデルに対し数cm〜十数cm弱のオーダーで妥当)。XMLとして\n  パース可能、パネルグループ8個、合印(ノッチ)128個(12シーム対応×両側2〜4個)。\n- 辺長歪み(±10%超の割合)はパネルごとに **47%〜82%**、面積比(2D\u002F3D)は\n  0.62〜1.13。momoのような複雑な形状(頭部・耳・手足の接合部を含むパネル)は\n  非可展性が強く、円筒・半球の単体テストと比べ歪みが大きい。ARAP反復回数を\n  5→40まで増やしても収束済み(59〜60%付近で頭打ち)であり、反復不足ではなく\n  幾何形状自体の限界であることを確認した(パネル分割の粒度を上げる・\n  分割線を可展になるよう誘導する等の改善はPhase 4c「シーム直線化」の対象)。\n\n### 既知の制限\n\n- 円盤位相の完全保証はしない。メッシュ自体が非多様体・多数の連結成分を\n  持つ場合(上記pixal3d例)、修復しきれないパネルが残りうる。\n- 平坦化(LSCM\u002FARAP)は円盤位相でないパネルには適用できず\n  `flatten_failed: true` としてSVGから除外される(型紙生成自体は継続する)。\n- 複雑な非可展形状(頭部・四肢の接合部等)では辺長歪みが大きくなりうる\n  (momo実測で±10%超が最大82%のパネルあり)。パネル分割を細かくする・\n  縫い代を大きめに取ることで布の伸縮により実用上は吸収可能な場合が多いが、\n  数学的な可展面保証はしない(仕様通りの制約)。\n- 縫い代オフセットは頂点法線方向オフセット+短エッジ間引きの簡易実装で、\n  自己交差を完全には排除しない(極端に凹んだ境界形状では縫い代線が\n  自己交差する可能性がある)。\n- 詰め物による膨張の逆補正・型紙の縫い合わせ長の厳密整合・シーム直線化・\n  PDF出力はPhase 4c以降。\n- `n_panels` は要求値の上限であり、極小パネル吸収により実際のパネル数は\n  それより少なくなることがある(`pattern.json` の `n_panels_actual` を\n  参照)。\n\n## Pixal3Dジェネレータ(MITライセンス、実機検証済み)\n\n[Pixal3D](https:\u002F\u002Fgithub.com\u002FTencentARC\u002FPixal3D)(TencentARC、SIGGRAPH 2026、\nTRELLIS.2基盤)を3つ目のジェネレータとして統合している。単一画像から\nPBRテクスチャ付きの3Dメッシュを生成し、本アプリではテクスチャの\nbaseColorを頂点カラーとしてサンプリングして活用する(GLBは頂点カラー付きで\n保存、`color_mode=color4` ではそのカラーから量子化・色分割3MFを出力)。\n\n### ライセンス上の利点\n\nHunyuan3D-2 が独自のコミュニティライセンス(地域制限・MAU制限)なのに対し、\n**Pixal3D はコードもモデル重みもMITライセンス**であり、ライセンス面での制約が\n大幅に少ない。\n\nGLB化のテクスチャベイク(`o_voxel.postprocess.to_glb`)には UV空間での平面\nラスタライズが必要で、upstream実装は nvdiffrast(NVIDIA Source Code License、\n**非商用限定**)に依存している。本アプリはこの依存を除去するため、\n`server\u002Fgenerators\u002Fpixal3d_raster.py` に **drtk(Meta製、MIT、\nhttps:\u002F\u002Fgithub.com\u002Ffacebookresearch\u002Fdrtk)** で同じ呼び出し規約\n(`RasterizeCudaContext` \u002F `rasterize` \u002F `interpolate`)を再現したシムを実装し、\n`to_glb` 呼び出し前に `o_voxel.postprocess.dr` をこのシムへ差し替える\n(`IMAGE3D_PIXAL3D_RASTERIZER`、既定 `auto`。詳細は次節)。\nこれにより既定構成では nvdiffrast を一切使用せず、GLB化経路もMITライセンス\nクリーンになる。nvdiffrastは drtk が利用できない環境向けの明示的フォールバック\nとしてのみ残している。\n\nただし、画像条件付けに使う **DINOv3 の重み**(`camenduru\u002Fdinov3-vitl16-pretrain-lvd1689m`、\nMetaの `facebook\u002Fdinov3-vit7b16-pretrain-lvd1689m` からの蒸留モデル)は\nMeta独自の **DINOv3 License** であり、完全なMITではない点に注意\n(商用利用自体は許可されているが、attribution表示等の付帯義務がある。\n詳細は「利用しているOSS」節の別表を参照)。以上より、Pixal3D構成は\n「コード全体がMIT」ではあるが、**DINOv3重みを含めた構成全体としては\n完全MITとは言えない**(重み・ライセンス面での完全クリーンではない)。\n\n### 隔離venvのセットアップ\n\nPixal3D は Python 3.10 と独自の依存ピン(trimesh==4.10.1 等)を要求するため、\n既存の `.venv`(Python 3.12)とは**完全に分離した専用venv `.venv-pixal3d`** を使う。\n既存venvには1パッケージも追加しない。手順の詳細・注意点は\n`requirements-pixal3d.txt` のコメントに集約してある。要約:\n\n```bash\n# 1. venv作成 + torch (Blackwell対応 cu128)\nuv venv .venv-pixal3d --python 3.10\nuv pip install --python .venv-pixal3d\u002Fbin\u002Fpython torch torchvision \\\n    --index-url https:\u002F\u002Fdownload.pytorch.org\u002Fwhl\u002Fcu128\n\n# 2. pip依存\nuv pip install --python .venv-pixal3d\u002Fbin\u002Fpython -r requirements-pixal3d.txt\n\n# 3. リポジトリclone(pipインストールせずsys.path経由でimportする)\ngit clone https:\u002F\u002Fgithub.com\u002FTencentARC\u002FPixal3D third_party\u002FPixal3D\ngit clone -b main --recursive https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FTRELLIS.2.git third_party\u002FTRELLIS.2\n\n# 4. CUDA拡張ビルド(CUDA 12.8ツールチェーンを明示。CUDACXXの明示が重要 —\n#    cmakeがシステム既定の \u002Fusr\u002Fbin\u002Fnvcc (CUDA 13.0) を拾うとglibcヘッダ非互換で失敗する)\nexport CUDA_HOME=\u002Fusr\u002Flocal\u002Fcuda-12.8\nexport CUDACXX=\u002Fusr\u002Flocal\u002Fcuda-12.8\u002Fbin\u002Fnvcc\nexport PATH=\"$CUDA_HOME\u002Fbin:$PATH\"\nexport TORCH_CUDA_ARCH_LIST=\"12.0\"\n\nuv pip install --python .venv-pixal3d\u002Fbin\u002Fpython --no-build-isolation third_party\u002FTRELLIS.2\u002Fo-voxel\n\n# ラスタライザ: drtk (MIT) を優先導入する。git経由のソースビルド (実測: sm_120で約3分40秒)。\nuv pip install --python .venv-pixal3d\u002Fbin\u002Fpython --no-build-isolation \\\n    \"git+https:\u002F\u002Fgithub.com\u002Ffacebookresearch\u002Fdrtk.git\"\n# nvdiffrast はdrtkが使えない場合のフォールバックのみ (非商用ライセンス、下記参照)。\n# drtkのみ導入していれば省略可。\nuv pip install --python .venv-pixal3d\u002Fbin\u002Fpython --no-build-isolation \\\n    \"git+https:\u002F\u002Fgithub.com\u002FNVlabs\u002Fnvdiffrast.git@v0.4.0\"\n\n# 5. NATTEN(NAF特徴アップサンプラの必須依存。sm_120ソースビルド、実測9分強)\nNATTEN_CUDA_ARCH=\"12.0\" NATTEN_N_WORKERS=8 uv pip install \\\n    --python .venv-pixal3d\u002Fbin\u002Fpython natten==0.21.0 --no-build-isolation\n```\n\nflash_attn は導入せず、**SDPAバックエンド**(`ATTN_BACKEND=sdpa` \u002F\n`SPARSE_ATTN_BACKEND=sdpa`)を使う(Blackwellでflash_attnのプリビルドが\ntorch ABI不一致のため)。モデル重みは初回生成時にHuggingFaceから自動DLされる\n(TencentARC\u002FPixal3D 約23GB + DINOv3 約1.2GB + NAF重み約2.5MB)。\n\n### 起動\n\n```bash\nenv IMAGE3D_GENERATOR=pixal3d ATTN_BACKEND=sdpa SPARSE_ATTN_BACKEND=sdpa \\\n    CUDA_HOME=\u002Fusr\u002Flocal\u002Fcuda-12.8 \\\n    .venv-pixal3d\u002Fbin\u002Fuvicorn server.main:app --host 127.0.0.1 --port 8022\n```\n\n`.claude\u002Flaunch.json` の `image3d-server-pixal3d`(ポート8022)にも同じ構成を\n定義済み。`IMAGE3D_GENERATOR=auto` では解決されない(明示指定のみ)。\n\n主な環境変数(`server\u002Fconfig.py`):\n\n| 変数 | デフォルト | 説明 |\n|---|---|---|\n| `IMAGE3D_PIXAL3D_LOW_VRAM` | `true` | 低VRAMモード(モデルCPU常駐、ステージごとにGPUへ) |\n| `IMAGE3D_PIXAL3D_RESOLUTION` | `1024` | パイプライン解像度(1024 \u002F 1536) |\n| `IMAGE3D_PIXAL3D_FOV` | `0.6` | カメラ水平FOV(ラジアン)。MoGe自動推定は不使用 |\n| `IMAGE3D_PIXAL3D_TEXTURE_SIZE` | `2048` | GLB化時のテクスチャベイクサイズ |\n| `IMAGE3D_PIXAL3D_MODEL_PATH` | `TencentARC\u002FPixal3D` | HFリポジトリID |\n| `IMAGE3D_PIXAL3D_RASTERIZER` | `auto` | `auto` \\| `drtk` \\| `nvdiffrast`。GLB化のUVテクスチャベイクに使うラスタライザ。`auto` はdrtk (MIT) がimport可能ならdrtkを使い、無ければnvdiffrast (非商用ライセンス) にフォールバックしてログ出力する。`drtk`\u002F`nvdiffrast` を明示指定した場合、それが利用不可だとエラーになる |\n\n### ラスタライザ切替(drtk \u002F nvdiffrast)\n\n`o_voxel.postprocess.to_glb` はUVアトラスへのテクスチャベイクに\n`RasterizeCudaContext` \u002F `rasterize` \u002F `interpolate` の3 APIを使う。upstream\n実装はこれを nvdiffrast (NVIDIA Source Code License、非商用限定) で呼んでいるが、\n本アプリは `server\u002Fgenerators\u002Fpixal3d_raster.py` に **drtk (Meta製、MIT)** で\n同じ呼び出し規約・戻り値規約を再現したシムを実装し、`Pixal3DGenerator` が\n`to_glb` 呼び出し直前に `o_voxel.postprocess.dr` をこのシムに差し替える\n(`select_rasterizer_module` \u002F `_inject_rasterizer`、`server\u002Fgenerators\u002Fpixal3d.py`)。\n\n- 座標系の差(nvdiffrastはOpenGL式でrow0=画像下端、drtkはピクセル座標で\n  row0=画像上端)はシム内でY軸反転により吸収し、シムの入出力はnvdiffrast\n  互換のまま維持している。\n- 重心座標の頂点対応(nvdiffrastの `u`\u002F`v` がどの頂点の重みに対応するか)は\n  実機でのA\u002FB検証(one-hot頂点属性を`interpolate`に通し、出力との相関を確認)\n  で確定させた(`u`=頂点0の重み、`v`=頂点1の重み)。\n- 実機A\u002FB検証(ランダムなUVメッシュ、数百面、nvdiffrastとdrtkシムの両方で\n  ラスタライズし比較): face IDマップの一致率99.9%以上(不一致は三角形境界の\n  1px差のみ)、一致した画素でのバリセントリック座標・interpolate結果は\n  浮動小数点誤差程度(最大差 ~1e-6)で一致することを確認済み。\n- drtk・nvdiffrastのどちらも未導入の場合は `RuntimeError`(明示的なエラー)\n  になる。\n\n### Hunyuan3D-2との比較実測値(RTX PRO 6000 Blackwell、momo.png、seed=42)\n\n| 項目 | Hunyuan3D-2(形状のみ) | Hunyuan3D-2(+texgen) | Pixal3D(1024・低VRAM・steps=30) |\n|---|---|---|---|\n| 生成時間(モデル常駐後) | 22〜35秒 | 60〜90秒 | 約97秒(生成+GLB化)+後処理21秒 |\n| 初回追加(モデルロード) | 数十秒 | 数十秒 | 約50〜60秒(23GB) |\n| プロセスVRAMピーク | 約12GB | 約25GB | **約18.7GB** |\n| テクスチャ\u002F色 | なし(投影方式で色付け) | 全周テクスチャ | **全周PBRテクスチャ→頂点カラー** |\n| watertight | true(体積計算可) | true | **false**(ボクセルリメッシュ由来、体積は0表示) |\n| メッシュ統計(momo.png) | 約109cm³ \u002F watertight | 同左 | 98,107頂点 \u002F 200,000面 \u002F bbox 67.4×48.3×100.0mm |\n| パレット(color4) | 投影ベース | テクスチャサンプル | テクスチャサンプル(白70% \u002F 紺21% \u002F 灰5% \u002F 赤4%) |\n| ライセンス | 独自(地域・MAU制限) | 同左 | **MIT(重みまで)** ※DINOv3重みは別ライセンス、下記OSS一覧参照 |\n\n- Pixal3D の生成時間は初回ジョブでさらに +2〜4分かかることがある\n  (FlexGEMMカーネルautotune・ラスタライザのJITコンパイルが初回のみ走るため。\n  2回目以降はディスクキャッシュで高速化)。\n- 低VRAMモード(既定)はステージごとにモデルをGPUへ載せ替えるため遅いが\n  ピークVRAMを抑える。96GB環境では `IMAGE3D_PIXAL3D_LOW_VRAM=false` +\n  `IMAGE3D_PIXAL3D_RESOLUTION=1536` で品質・速度を上げられる(未計測)。\n\n**drtkバックエンドでのE2E再検証(2026-07-09、ポート8022、\n`IMAGE3D_PIXAL3D_RASTERIZER=drtk`明示指定、momo.png、seed=42、color_mode=color4)**:\n\n| 項目 | nvdiffrastバックエンド(ジョブ58d8e1d0) | drtkバックエンド(ジョブb716c24a、本検証) |\n|---|---|---|\n| 総所要時間(モデルロード込み) | — | 121秒(モデルロード含む初回実行) |\n| 頂点数 | 98,107 | 98,105 |\n| 面数 | 200,000 | 200,000 |\n| bbox (mm) | 67.37 × 48.30 × 100.02 | 67.38 × 48.35 × 100.03 |\n| watertight | false | false |\n| パレット(color4) | 白70% \u002F 紺21% \u002F 灰5% \u002F 赤4% | 白系44% \u002F 水色系28% \u002F 紺系23% \u002F 灰系5%(構成比) |\n\n頂点数・面数・bboxはほぼ完全に一致しており、drtkベースのラスタライズが\nnvdiffrast版と幾何学的に等価な結果を生成することを確認した(GLBの頂点カラーも\n正常にサンプリング・保存されていることを確認済み)。パレットの正確な色相・\n構成比はジョブ間で差があるが、これは拡散サンプリングそのものの実行間非決定性\n(torch\u002FCUDAのattentionカーネル等)によるもので、ラスタライザ差とは無関係\n(頂点\u002F面数\u002Fbboxのメッシュ形状自体は同一シードで再現しているため)。\n\n### 制限・実装メモ\n\n- **マルチビュー入力(FR-9)非対応**: `image_back` 等を指定するとジョブは\n  明示的なエラーで失敗する。単一画像専用。\n- **texture_mode=paint 非対応**: texgen は hy3dgen 依存のため `.venv-pixal3d`\n  では利用不可(paint指定時は警告を記録して投影方式にフォールバック)。\n  そもそも Pixal3D 自体が全周テクスチャを生成するため不要。\n- **パラメータは steps \u002F seed のみ接続**: guidance_scale \u002F octree_resolution は\n  Pixal3D のステージごとに調整済みの既定値と互換性が無いため無視される。\n  steps はデフォルト30だが、Pixal3D 公式デフォルトは12(30でも動作するが\n  サンプリングが遅くなる。速度優先なら steps=12 を指定)。\n- **背景除去必須**: Pixal3D 公式の背景除去モデル(briaai\u002FRMBG-2.0)はHFの\n  ゲート付きリポジトリのためロードせず、本アプリの背景除去(rembg CPU)の\n  結果を渡す。`remove_bg=false` でアルファ無し画像を送るとエラーになる。\n- **watertightにならない**: ボクセルリメッシュ出力は閉じたソリッドではなく、\n  体積は0と表示される。スライサーでの印刷は通常問題ないが、体積ベースの\n  見積りはできない。確実なwatertightが必要なら hunyuan3d を使う。\n- **UVシーム由来の頂点分断は自動修復**: `o_voxel` のGLB出力はUVアトラス境界で\n  頂点が複製され数万個の連結成分に分断されているため、ジェネレータ内で\n  頂点溶接(`merge_vertices`)してから後処理に渡す(これを外すと\n  浮遊小部品除去が本体表面を削除してしまう。server\u002Fgenerators\u002Fpixal3d.py参照)。\n- **座標系**: Pixal3D のGLB出力は 上=-Z \u002F 正面=+Y(実測確認)。X軸まわり\n  180°回転で本アプリの Z-up \u002F 正面=-Y に変換している。\n- **カメラFOVは固定値**: 公式の MoGe による自動FOV推定は導入していない\n  (`IMAGE3D_PIXAL3D_FOV`、既定0.6rad ≈ 34°)。入力画像の遠近感が強い場合は\n  調整の余地がある。\n\n## リポジトリ構成\n\n```\nimage-3d\u002F\n├── docs\u002F                     # 仕様書・開発方針・実装計画\n├── server\u002F\n│   ├── main.py               # FastAPIエントリポイント\n│   ├── config.py             # 設定(環境変数)\n│   ├── jobs.py               # ジョブ管理・直列実行キュー・永続化\n│   ├── generators\u002F\n│   │   ├── base.py           # Generator抽象基底\n│   │   ├── mock.py           # mockジェネレータ\n│   │   ├── hunyuan3d.py      # Hunyuan3D-2ラッパ(Phase 2、Phase 3aでmvパイプライン追加)\n│   │   └── pixal3d.py        # Pixal3Dラッパ(MITライセンス、専用venv .venv-pixal3d で使用)\n│   ├── preprocess.py         # 画像前処理(背景除去・リサイズ)\n│   ├── meshproc.py           # メッシュ後処理\n│   ├── colorproc.py          # 4色カラープリント対応(Phase 2.5、頂点カラー投影・量子化・分割)\n│   ├── sheet.py              # キャラクターシート自動分割(Phase 3a、パネル検出)\n│   ├── texture.py            # テクスチャ生成 texgen 統合(Phase 3c、paint常駐ラッパ・頂点カラーサンプリング)\n│   └── pattern\u002F               # ぬいぐるみ型紙生成(Phase 4a+4b、純粋モジュール。numpy\u002Fscipy\u002Ftrimeshのみに依存)\n│       ├── preprocess.py     # prepare_mesh(): 平滑化+簡略化+最大連結成分抽出\n│       ├── segment.py        # segment_panels(): パネル分割(円盤位相保証・色境界誘導)\n│       ├── preview.py        # build_preview_mesh(): パネル色分けプレビューメッシュ\n│       ├── flatten.py        # flatten_panel(): LSCM+ARAPによる2D展開・歪み指標(Phase 4b)\n│       └── svg.py            # build_pattern_svg(): 実寸SVG型紙(縫い代・合印・布目線、Phase 4b)\n├── web\u002F                      # 静的フロントエンド\n├── tests\u002F                    # pytest\n├── data\u002Fjobs\u002F                # 生成物(gitignore対象)\n├── third_party\u002FHunyuan3D-2\u002F  # hy3dgen本体(git clone、Phase 2、gitignore対象)\n├── third_party\u002FPixal3D\u002F      # Pixal3D本体(git clone、gitignore対象)\n├── third_party\u002FTRELLIS.2\u002F    # o-voxelビルド用(git clone、gitignore対象)\n├── requirements.txt          # base依存\n├── requirements-gpu.txt      # Phase 2用追加依存\n├── requirements-pixal3d.txt  # Pixal3D用隔離venv (.venv-pixal3d) の依存(セットアップ手順込み)\n├── run.sh\n└── README.md\n```\n\n## よくある質問(FAQ)\n\n### Q. アップロードした画像と関係ないテスト形状(同じ形)ばかり生成される\n\nmockジェネレータで動作しています。UIヘッダ右上の「生成エンジン」バッジが\n`mock` になっていないか確認してください(mock時は画面上部に警告バナーも出ます)。\n対処は「[アップロード画像と無関係なテスト形状が生成されるとき](#アップロード画像と無関係なテスト形状が生成されるとき)」を参照。\n旧バージョンのアプリでは `IMAGE3D_GENERATOR=hunyuan3d` を明示指定してください\n(`auto` は新バージョンのみ対応)。\n\n### Q. GPUなしでも使えますか?\n\nUIやAPIの動作確認はmockジェネレータでGPU不要で行えます。ただし実際の画像から\n3Dを生成するにはNVIDIA GPUが必須です(形状生成のみ VRAM 16GB以上、テクスチャ\n生成併用は 32GB以上。実測値は「VRAM最小要件」の表を参照)。CPUのみでの実生成は\nサポートしていません。\n\n### Q. 生成にどれくらい時間がかかりますか?\n\n本README記載の実測環境(RTX PRO 6000)で、形状のみ約20〜40秒、テクスチャ生成\n併用で約60〜90秒です。**初回だけ**はモデルのダウンロード(単一ビュー約9.2GB、\nマルチビュー約9.2GB、テクスチャ用モデル数GB)とロード(十数秒〜)が加わるため、\n数分〜数十分かかることがあります。2回目以降はモデルが常駐するため速くなります。\n\n### Q. 初回生成時のモデルはどこに保存されますか? オフラインで使えますか?\n\nHuggingFaceのキャッシュ(既定 `~\u002F.cache\u002Fhuggingface`)に保存されます。\n一度ダウンロードすれば、以降の生成はインターネット接続なしで動作します。\n\n### Q. 「watertight: NG」と表示されました。印刷できませんか?\n\n多くの場合そのまま印刷できます。後処理で穴埋めを試みても閉じきらなかった\nことを示す表示で、最近のスライサー(Bambu Studio \u002F PrusaSlicer 等)は読み込み時に\n自動修復します。気になる場合は `octree_resolution` を1段下げる、`seed` を変えて\n再生成する、スライサーの修復機能(またはWindowsの3D Builder等)を使う、の\nいずれかで解消できることが多いです。\n\n### Q. 4色の3MFをスライサーでどう使えばいいですか?\n\nカラーモードで出力した3MFには `color_1`〜`color_4` の最大4オブジェクトが\n入っています。Bambu Studio \u002F PrusaSlicer で開き、オブジェクトごとに\nAMS \u002F MMU のフィラメント(スロット)を割り当ててスライスしてください。\nアプリの「パレット」表示(色チップ+比率)が各オブジェクトの色の目安です。\n\n### Q. 4色以外(2色・3色、あるいは5色以上)にできますか?\n\n`n_colors` パラメータで2〜4色を指定できます。5色以上は対応していません\n(4スロットのAMSを想定した仕様です)。\n\n### Q. キャラクターシートのパネルがうまく検出されません\n\n自動分割はパネル同士が離れていて背景とのコントラストがある構図を前提とした\n簡易解析です。検出に失敗する場合は、シートを画像編集ソフトで切り分けて、\n正面\u002F背面\u002F側面の各アップロード欄に個別に登録してください(生成品質は同じです)。\n\n### Q. 「テクスチャ生成(実験的)」のチェックボックスが押せません\n\nその環境でtexgen(CUDA拡張)が利用できないことを示します(`\u002Fapi\u002Fhealth` の\n`texgen_available` が `false`)。「Phase 3c」節のビルド手順(torchのCUDAバージョンと\n一致するCUDAツールチェーンが必要)を実施してください。ビルドしなくても、\n正面投影方式の4色カラー出力(FR-8)は利用できます。\n\n### Q. 生成物のサイズ(高さ)を変えたい \u002F 印刷に適したポリゴン数は?\n\n「目標高さ(mm)」で出力サイズを指定できます(既定100mm、Z軸高さ基準で\nスケーリング+接地済み)。面数は既定20万面で一般的なFDM印刷には十分です。\nプリセット(フィギュア\u002F小型フィギュア\u002Fペンダント\u002F高精細)を使うと、\n高さ・解像度・面数をまとめて切り替えられます。\n\n### Q. スライス(Gコード生成)やサポート材の生成はできますか?\n\nできません。本アプリはプリント可能なメッシュデータ(STL\u002F3MF)の生成までを担当し、\nスライスはスライサー(Bambu Studio \u002F PrusaSlicer \u002F Cura 等)の役割です(SPEC.md §7)。\nビューアの「オーバーハング」表示で、サポートが必要になりそうな箇所(既定45°超)を\n事前に確認できます。\n\n### Q. 商用利用できますか?\n\n本プロジェクトのコードは [Polyform Small Business License](LICENSE)(小規模事業者\nまで商用可)ですが、**生成に使うHunyuan3D-2モデルはTencentのコミュニティ\nライセンスに別途従う必要があります**(利用地域・規模の制限あり)。\n詳細は「ライセンス」節を参照してください。\n\n### Q. `third_party\u002FHunyuan3D-2` を入れ直したらテクスチャ生成が壊れました\n\n再clone時はvendoredパッチ(`hy3dgen\u002Ftexgen\u002Futils\u002Fmultiview_utils.py` の\n`trust_remote_code=True`)の再適用が必要です。「Phase 3c」節の手順を参照してください。\n\n## 既知の制限\n\n- mockジェネレータは画像内容を反映しない決定的な形状(seedでバリエーション)を返す。\n  実際の画像に基づく生成にはPhase 2でのHunyuan3D-2導入が必要。mockジェネレータは\n  マルチビュー入力(`extra_views`)を無視する(単一ビュー用の決定的形状を返す)。\n- マルチビュー生成(FR-9)は `hunyuan3d-dit-v2-mv` モデル(約9.2GB、単一ビュー用\n  モデルとは別リポジトリ `tencent\u002FHunyuan3D-2mv`)の追加ダウンロードが必要。\n  厳密なマルチビュー幾何整合(正面・背面・側面の完全な形状一致)はモデル自体の\n  性能に依存し、本アプリ側での補正は行わない(SPEC.md §7の制約通り)。\n- キャラクターシート自動分割(`server\u002Fsheet.py`)は、パネル同士が明確に離れて\n  いる・背景とのコントラストがある構図を前提とした簡易的な連結成分解析であり、\n  パネルが複雑に重なる・背景と被写体の色が近いシートでは誤検出する場合がある\n  (その場合はUI上で手動修正が必要)。\n- テクスチャ生成AIによるカラー3Dプリント(Hunyuan3D-2 paint pipeline)は\n  Phase 3cで `texture_mode=paint` として対応済み(上記「Phase 3c」参照)。\n  ビルド・依存が利用できない環境では自動的に無効化され、Phase 2.5の\n  入力画像の正面\u002F背面投影+k-means量子化による簡易4色対応(`server\u002Fcolorproc.py`)に\n  フォールバックする。\n- `hy3dgen` はPyPI未配布のため、`third_party\u002FHunyuan3D-2` をgit cloneしての\n  editableインストール(`--no-deps`)が必要。\n- Hunyuan3D-2の生成メッシュは非watertightで返る場合が通常であり、\n  `meshproc.process()` の後処理(穴埋め・簡略化)により実用上のwatertight化を\n  行う。まれに複雑な形状で後処理後もwatertight化に失敗する場合があり、\n  その際は `stats.watertight=false` としてUIに明示される(SPEC.md FR-4)。\n- カラーモード(FR-8)は背景除去済み画像の正面\u002F背面投影で頂点カラーを決める。\n  追加ビューに背面画像が無い場合、背面側と側面\u002F上下の曖昧な頂点はベース色に\n  なるため、実際の側面・背面の配色とは一致しない場合がある。\n- 3MFの色ごとのサブメッシュ(`color_1`〜`color_4`)は単体ではwatertightと\n  限らない(積層方式のマルチカラー印刷では通常問題にならない)。\n- パレット量子化はRGB色空間での単純なk-means(scipy.cluster.vq.kmeans2)で\n  あり、知覚色差(CIE Lab等)は考慮していない。\n\n## ライセンス\n\nこのリポジトリ(`server\u002F`・`web\u002F`・`docs\u002F`・`tests\u002F` 等、本プロジェクトのオリジナル\nコード)は [Polyform Small Business License 1.0.0](LICENSE) の下で提供されます。\n\n要約(法的拘束力があるのは[LICENSE](LICENSE)本文のみです)。Hunyuan3D-2 \u002F\nPixal3D(DINOv3)を有効にする場合の所定の謝辞・Notice文言は\n[NOTICE](NOTICE) にまとめてあります(UIにも `IMAGE3D_GENERATOR=pixal3d` 時に\n\"Built with DINOv3\" を表示します):\n\n- **非商用利用**は誰でも自由に可能。\n- **商用利用**も、利用者の所属組織が\n  - 従業員・業務委託者を合わせて100人未満、かつ\n  - 直近の課税年度の総収益が100万USD未満(1982〜1984年基準のCPIで物価調整)\n\n  の「小規模事業者」に該当する場合は許可されます。上記条件を満たさない大企業\n  による商用利用のみが制限されます。\n- 個人利用・小規模団体の商用利用は上記の通り許可されるため、条件を除外(許可)\n  しています。\n\n**third_party\u002FHunyuan3D-2 は対象外**: このリポジトリには含まれず(`.gitignore`\n対象)、利用者が別途 `git clone` して導入します。Tencentの\n`TENCENT HUNYUAN 3D 2.0 COMMUNITY LICENSE AGREEMENT`\n(`third_party\u002FHunyuan3D-2\u002FLICENSE`)など、それぞれの配布元のライセンス条件に\n従ってください(利用地域制限・利用者数に応じた追加許諾要件などが定められて\nいます)。\n\n### Hunyuan3D-2構成での主な利用条件と、配布・サービス提供時の付帯義務\n\n`third_party\u002FHunyuan3D-2\u002FLICENSE`(2026-07時点の原文)に基づく要約。\n法的拘束力があるのは原文のみであり、本節は法的助言ではありません。\n\n**利用条件(使うだけの場合も適用)**:\n\n- **地域**: EU・英国・韓国では利用不可(Territory外)。生成物(Output)を\n  Territory外で使用・表示することも許諾されない。\n- **規模**: 全製品・サービス合計の月間アクティブユーザーが**100万人**を超える\n  事業者は、Tencentへの別途ライセンス申請が必要。\n\n**本アプリ(Hunyuan3D-2構成)を第三者に配布、またはサービスとして提供する場合の\n付帯義務**(同ライセンス §3):\n\n1. 受領者にTencentライセンス本文の写しを提供すること(§3(a))\n2. Hunyuan3D-2側のファイルを変更した場合は、変更した旨の告知を目立つ形で\n   付すこと(§3(b))\n3. ホステッドサービス以外の配布物には、所定の文言のNoticeテキストファイルを\n   同梱すること(§3(d)。文言はライセンス原文参照)\n4. サービス・製品の実際の提供者(法人名等)を明示し、**Tencentが提携・後援して\n   いると誤認させる表示をしない**こと(§3(e))\n5. 「Powered by Tencent Hunyuan」表示と技術紹介記事の公開は推奨(encouraged)で\n   あり義務ではない(§3(c))\n\nなお、Pixal3D構成の場合は上記のTencentライセンスは適用されません。\n既定のラスタライザ構成(drtk、MIT)では nvdiffrast(非商用ライセンス)への\n依存も無くなりましたが、画像条件付けに使う **DINOv3 の重み**\n(Meta独自ライセンス、商用利用可・attribution等の付帯義務あり)が別途\n制約になります(「Pixal3Dジェネレータ」節・OSS一覧参照)。\n\n### 利用しているOSS\n\n`requirements*.txt` に列挙されたPython依存パッケージ、および同梱の\nフロントエンドライブラリは、それぞれ独自のOSSライセンス下にあります(本プロジェクト\n自体のライセンスとは別)。主要なものは以下の通りです(ライセンス表記は各配布元の\n情報に基づく参考情報であり、正確な条件は各プロジェクトの配布物・パッケージ情報を\n必ず確認してください)。\n\n**バックエンド (`requirements.txt`)**\n\n| パッケージ | ライセンス |\n|---|---|\n| FastAPI | MIT |\n| Uvicorn | BSD-3-Clause |\n| python-multipart | Apache-2.0 |\n| trimesh | MIT |\n| SciPy | BSD-3-Clause |\n| NetworkX | BSD-3-Clause |\n| lxml | BSD-3-Clause |\n| NumPy | BSD-3-Clause |\n| Pillow | MIT-CMU (HPND系) |\n| fast-simplification | MIT |\n| pytest | MIT |\n| HTTPX | BSD-3-Clause |\n\n**GPU\u002FHunyuan3D-2連携 (`requirements-gpu.txt`)**\n\n| パッケージ | ライセンス |\n|---|---|\n| rembg | MIT |\n| onnxruntime | MIT |\n| PyTorch \u002F torchvision | BSD-3-Clause |\n| huggingface_hub | Apache-2.0 |\n| einops | MIT |\n| OmegaConf | BSD-3-Clause |\n| Transformers | Apache-2.0 |\n| Diffusers | Apache-2.0 |\n| Accelerate | Apache-2.0 |\n| opencv-python-headless | MIT(同梱のOpenCV本体はApache-2.0) |\n| scikit-image | BSD-3-Clause |\n| **pymeshlab** | **GPL-3.0**(デュアルライセンス、商用ライセンスも別途提供)。本プロジェクト自身のコード(`server\u002F`)からは呼び出しておらず、`third_party\u002FHunyuan3D-2`(hy3dgen)側の内部依存として使用される。GPLの条件に懸念がある場合は導入を見送ることも可能(その場合hy3dgen側の一部後処理機能が制限される可能性があります)。 |\n| xatlas | MIT |\n| pybind11 | BSD-3-Clause |\n| Ninja | Apache-2.0 |\n| pygltflib | MIT |\n\n**フロントエンド (`web\u002Fvendor\u002F`)**\n\n| ライブラリ | ライセンス |\n|---|---|\n| Three.js (r160, `web\u002Fvendor\u002Fthree\u002F`) | MIT |\n\n**別リポジトリのモデル(`third_party\u002F`、本リポジトリには含まれない)**\n\n| 対象 | ライセンス |\n|---|---|\n| Tencent Hunyuan3D-2 (hy3dgen) | TENCENT HUNYUAN 3D 2.0 COMMUNITY LICENSE AGREEMENT(独自ライセンス。地域制限・月間アクティブユーザー数100万人超での別途許諾要件あり) |\n| TencentARC Pixal3D(コード+モデル重み) | MIT(コード・重みともにMIT。ただし画像条件付けに使うDINOv3重みは別ライセンス、下記参照) |\n| Microsoft TRELLIS.2 \u002F o-voxel | MIT |\n| JeffreyXiang CuMesh(o-voxelのビルド時依存、GitHub直接取得) | MIT |\n| JeffreyXiang FlexGEMM(o-voxelのビルド時依存、GitHub直接取得) | MIT |\n| **Meta drtk**(既定のラスタライザ。`server\u002Fgenerators\u002Fpixal3d_raster.py` 経由で使用、実機検証済み) | **MIT** |\n| NVlabs nvdiffrast(drtkが使えない場合のみのフォールバック。既定構成では未使用) | NVIDIA Source Code License(非商用研究用途。商用利用はNVIDIAの許諾が必要な点に注意) |\n| NATTEN | MIT |\n| valeoai NAF(NAFアップサンプラ重み、torch.hub経由) | Apache-2.0 |\n| **Meta DINOv3 重み**(`camenduru\u002Fdinov3-vitl16-pretrain-lvd1689m`、Meta `facebook\u002Fdinov3-vit7b16-pretrain-lvd1689m` からの蒸留モデル。Pixal3Dの画像条件付けに使用) | **DINOv3 License**(Meta独自ライセンス、MITではない)。[ライセンス原文](https:\u002F\u002Fai.meta.com\u002Fresources\u002Fmodels-and-libraries\u002Fdinov3-license\u002F)の要約(法的拘束力は原文のみ): 商用利用は**許可**されており、企業規模・地域・MAU等による制限は無い。ただし (1) 再配布時はライセンス原文の写しを同梱すること、(2) 関連するWebサイト・UI・製品ドキュメント等に \"Built with DINOv3\" の表示を行うこと、(3) 研究成果を公開する場合はDINO Materialsの利用を謝辞に記載すること、(4) リバースエンジニアリング禁止、(5) 軍事・兵器・ITAR対象活動などへの利用禁止、が付帯義務として定められている。utils3d(upstream inference.pyのレンダリング\u002F学習系専用ライブラリ)は本アプリの生成経路では使用しないため未導入。 |\n\n**まとめ**: Pixal3D構成は「コード全体(Pixal3D本体・TRELLIS.2\u002Fo-voxel・CuMesh\u002F\nFlexGEMM・drtk・NATTEN)はMIT」であり、既定のラスタライザ構成\n(`IMAGE3D_PIXAL3D_RASTERIZER=auto` かつdrtk導入済み)では nvdiffrast\n(非商用ライセンス)を一切使用しない。しかし**画像条件付けに使うDINOv3の\n重みがMeta独自ライセンス**であるため、**構成全体としては「完全MIT」とは\n言えない**(商用利用自体は許可される緩やかなライセンスだが、attribution等の\n付帯義務がある点に注意)。\n","这是一个将2D图像转换为可3D打印模型的本地Web应用，支持生成STL、3MF、GLB和OBJ格式文件。核心功能包括图像预处理、参数化网格生成（mock）、Hunyuan3D-2与Pixal3D等AI模型集成、多视角输入处理、4色打印适配、纹理生成及毛绒玩具纸样（SVG）自动展开。技术上采用FastAPI后端与Three.js前端，支持CPU基础模式与GPU加速双路径，具备VRAM感知调度与健康状态反馈。适用于个人创作者、手办爱好者及小批量原型设计者在本地完成从图片到实体模型的端到端流程。",2,"2026-07-09 02:30:23","CREATED_QUERY"]