# 画面設計書 10-Menubar - File

## 概要

three.js EditorのMenubar - Fileメニューの設計書。本ドキュメントでは、プロジェクトの新規作成、開く、保存、インポート、エクスポート機能について詳細に記述する。

### 本画面の処理概要

Menubar - Fileメニューは、プロジェクトファイルの入出力を管理するためのメニューである。新規プロジェクトの作成（空のプロジェクトまたはサンプルプロジェクト）、既存プロジェクトを開く、現在のプロジェクトを保存、外部3Dモデルのインポート、および各種フォーマット（DRC、GLB、GLTF、OBJ、PLY、STL、USDZ）へのエクスポート機能を提供する。

**業務上の目的・背景**：3Dエディタの基本機能として、ユーザーが作成したシーンを保存・読み込みできることが不可欠である。また、外部で作成された3Dモデルをインポートしたり、他のツールで使用するためにエクスポートする必要がある。本メニューにより、様々な3Dフォーマットとの相互運用性を実現し、3D制作ワークフローに柔軟に対応できる。

**画面へのアクセス方法**：Menubarの「File」をクリックしてメニューを展開。

**主要な操作・処理内容**：
1. 新規プロジェクト作成（Empty / サンプルプロジェクト）
2. プロジェクトを開く（JSONファイル）
3. プロジェクトを保存（project.json）
4. 外部ファイルのインポート
5. 各種フォーマットへのエクスポート

**画面遷移**：各操作はモーダルまたはファイルダイアログを表示。操作完了後はエディタ画面に戻る。

**権限による表示制御**：権限による制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Loader | 主機能 | ファイルのインポート処理 |
| 2 | Exporter | 主機能 | 各種フォーマットへのエクスポート処理 |

## 画面種別

メニュー / ドロップダウン

## URL/ルーティング

URLルーティングなし（エディタ内コンポーネント）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|----------|------|
| Project JSON | 入出力 | File | プロジェクトファイル |
| Import Files | 入力 | File[] | インポートする3Dモデルファイル |
| Export File | 出力 | File | エクスポートされたファイル |

## 表示項目

| 要素 | 表示内容 | 説明 |
|------|----------|------|
| New | サブメニュー | 新規プロジェクト作成 |
| New > Empty | メニュー項目 | 空のプロジェクト |
| New > Arkanoid | メニュー項目 | Arkanoidサンプル |
| New > Camera | メニュー項目 | Cameraサンプル |
| New > Particles | メニュー項目 | Particlesサンプル |
| New > Pong | メニュー項目 | Pongサンプル |
| New > Shaders | メニュー項目 | Shadersサンプル |
| Open | メニュー項目 | プロジェクトを開く |
| Save | メニュー項目 | プロジェクトを保存 |
| Import | メニュー項目 | ファイルをインポート |
| Export | サブメニュー | エクスポート |
| Export > DRC | メニュー項目 | Draco形式 |
| Export > GLB | メニュー項目 | glTF Binary形式 |
| Export > GLTF | メニュー項目 | glTF形式 |
| Export > OBJ | メニュー項目 | Wavefront OBJ形式 |
| Export > PLY | メニュー項目 | PLY ASCII形式 |
| Export > PLY (BINARY) | メニュー項目 | PLY Binary形式 |
| Export > STL | メニュー項目 | STL ASCII形式 |
| Export > STL (BINARY) | メニュー項目 | STL Binary形式 |
| Export > USDZ | メニュー項目 | USDZ形式 |

## イベント仕様

### 1-新規プロジェクト作成（Empty）

空のプロジェクトを作成する処理。

1. 「New > Empty」をクリック（行47-56）
2. 確認ダイアログを表示（`confirm(strings.getKey('prompt/file/open'))`）
3. 承諾された場合、`editor.clear()`を実行
4. シーンがリセットされ、デフォルト状態になる

### 2-新規プロジェクト作成（サンプル）

サンプルプロジェクトを読み込む処理。

1. サンプル項目をクリック（行75-102）
2. 確認ダイアログを表示
3. 承諾された場合、`FileLoader`でサンプルJSONを読み込み
4. `editor.clear()`でシーンをリセット
5. `editor.fromJSON()`でサンプルを読み込み

### 3-プロジェクトを開く

既存プロジェクトファイルを開く処理。

1. 「Open」をクリック（行151-162）
2. 確認ダイアログを表示
3. ファイル選択ダイアログを表示（.json形式のみ）
4. ファイル選択後、JSONをパース（行114-145）
5. `editorCleared`シグナルにハンドラを登録
6. `editor.clear()`を実行
7. クリア完了後、`editor.fromJSON()`でプロジェクトを読み込み
8. エラー時はアラート表示

### 4-プロジェクトを保存

現在のプロジェクトをJSON形式で保存する処理。

1. 「Save」をクリック（行168-177）
2. `editor.toJSON()`でシーンをシリアライズ
3. `Blob`を作成してダウンロード（project.json）

### 5-ファイルインポート

外部3Dモデルファイルをインポートする処理。

1. 「Import」をクリック（行202-209）
2. ファイル選択ダイアログを表示（複数選択可能）
3. `editor.loader.loadFiles()`でファイルを読み込み（行194-199）
4. 対応フォーマットはLoaderが自動判定

### 6-DRCエクスポート

選択オブジェクトをDraco形式でエクスポートする処理。

1. 「Export > DRC」をクリック（行236-268）
2. 選択オブジェクトがMeshか確認
3. Meshでない場合はアラート表示
4. `DRACOExporter`を動的インポート
5. オプション設定（decodeSpeed、encodeSpeed、quantization等）
6. `exporter.parse()`でエンコード
7. `saveArrayBuffer()`でダウンロード（model.drc）

### 7-GLBエクスポート

シーン全体をglTF Binary形式でエクスポートする処理。

1. 「Export > GLB」をクリック（行273-299）
2. `getAnimations()`でシーン内のアニメーションを収集
3. アニメーションを最適化（clone().optimize()）
4. `GLTFExporter`を動的インポート
5. `exporter.parse()`でバイナリ形式で出力
6. `saveArrayBuffer()`でダウンロード（scene.glb）

### 8-GLTFエクスポート

シーン全体をglTF形式（JSON）でエクスポートする処理。

1. 「Export > GLTF」をクリック（行304-331）
2. `getAnimations()`でシーン内のアニメーションを収集
3. アニメーションを最適化
4. `GLTFExporter`を動的インポート
5. `exporter.parse()`でJSON形式で出力
6. `saveString()`でダウンロード（scene.gltf）

### 9-OBJエクスポート

選択オブジェクトをOBJ形式でエクスポートする処理。

1. 「Export > OBJ」をクリック（行336-356）
2. 選択オブジェクトの有無を確認
3. オブジェクトがない場合はアラート表示
4. `OBJExporter`を動的インポート
5. `exporter.parse()`でテキスト形式で出力
6. `saveString()`でダウンロード（model.obj）

### 10-PLYエクスポート

シーン全体をPLY形式でエクスポートする処理。

1. 「Export > PLY」または「PLY (BINARY)」をクリック（行361-396）
2. `PLYExporter`を動的インポート
3. `exporter.parse()`で出力（ASCII/Binaryオプション）
4. `saveArrayBuffer()`でダウンロード（model.ply / model-binary.ply）

### 11-STLエクスポート

シーン全体をSTL形式でエクスポートする処理。

1. 「Export > STL」または「STL (BINARY)」をクリック（行401-428）
2. `STLExporter`を動的インポート
3. `exporter.parse()`で出力（ASCII/Binaryオプション）
4. ASCII: `saveString()`、Binary: `saveArrayBuffer()`でダウンロード

### 12-USDZエクスポート

シーン全体をUSDZ形式でエクスポートする処理。

1. 「Export > USDZ」をクリック（行433-444）
2. `USDZExporter`を動的インポート
3. `exporter.parseAsync()`で非同期出力
4. `saveArrayBuffer()`でダウンロード（model.usdz）

## データベース更新仕様

### 操作別データベース影響一覧

Menubar - File単体でのデータベース操作はない。プロジェクトの永続化はIndexedDBの自動保存機能で行われる。

## メッセージ仕様

| 種別 | キー | メッセージ内容 | 表示条件 |
|------|------|--------------|----------|
| 確認 | prompt/file/open | 現在のプロジェクトを破棄しますか？ | New/Open実行時 |
| エラー | prompt/file/failedToOpenProject | プロジェクトを開けませんでした | JSONパースエラー時 |
| エラー | prompt/file/export/noMeshSelected | Meshが選択されていません | DRCエクスポート時 |
| エラー | prompt/file/export/noObjectSelected | オブジェクトが選択されていません | OBJエクスポート時 |

## 例外処理

| 状況 | 処理 |
|------|------|
| JSONパースエラー | アラート表示、コンソールにエラー出力 |
| DRC/OBJエクスポート時に対象がない | アラート表示して中断 |
| エクスポーターの動的インポート失敗 | 例外がスローされる（明示的なハンドリングなし） |

## 備考

- エクスポーターは動的インポート（`await import()`）で必要時のみ読み込み
- サンプルプロジェクトは`examples/`ディレクトリから読み込み
- FileLoaderはthree.jsのコア機能を使用
- DRCエクスポートは選択オブジェクト単体、他のエクスポートはシーン全体が対象
- OBJエクスポートは選択オブジェクトのみが対象
- アニメーションはGLB/GLTFエクスポート時のみ含まれる
- `saveArrayBuffer`と`saveString`は`editor.utils`から取得

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: メニュー構造を理解する

Fileメニューの全体構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Menubar.File.js | `editor/js/Menubar.File.js` | 行4-467でメニュー全体構成 |

**主要処理フロー**:
1. **行11-21**: UIPanel作成、メニュータイトル設定
2. **行23-102**: Newサブメニュー（Empty + サンプル5種）
3. **行104-164**: Open処理（ファイル選択とJSON読み込み）
4. **行166-179**: Save処理（toJSON + Blobダウンロード）
5. **行185-210**: Import処理（loader.loadFiles）
6. **行212-445**: Exportサブメニュー（9種のフォーマット）

#### Step 2: プロジェクト入出力を理解する

Open/Save処理の詳細を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Menubar.File.js | `editor/js/Menubar.File.js` | 行104-179 |
| 2-2 | Editor.js | `editor/js/Editor.js` | toJSON/fromJSONメソッド |

**Open処理フロー**:
1. **行106-149**: openProjectFormとinput要素の作成
2. **行114-145**: changeイベントでファイル読み込み
3. **行120-130**: editorClearedシグナル経由でfromJSON呼び出し

**Save処理フロー**:
1. **行168-177**: toJSON → Blob → save呼び出し

#### Step 3: エクスポーターを理解する

各種エクスポーターの実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Menubar.File.js | `editor/js/Menubar.File.js` | 行234-445 |

**エクスポーター一覧**:
| エクスポーター | 行番号 | 動的インポート元 |
|--------------|--------|-----------------|
| DRACOExporter | 236-268 | three/addons/exporters/DRACOExporter.js |
| GLTFExporter | 273-331 | three/addons/exporters/GLTFExporter.js |
| OBJExporter | 336-356 | three/addons/exporters/OBJExporter.js |
| PLYExporter | 361-396 | three/addons/exporters/PLYExporter.js |
| STLExporter | 401-428 | three/addons/exporters/STLExporter.js |
| USDZExporter | 433-444 | three/addons/exporters/USDZExporter.js |

### プログラム呼び出し階層図

```
Menubar.File.js
    │
    ├─ UIPanel (container)
    │      ├─ title ("File")
    │      └─ options (menu items)
    │
    ├─ New (submenu)
    │      ├─ Empty → editor.clear()
    │      └─ Samples → FileLoader.load() → editor.fromJSON()
    │
    ├─ Open → openProjectInput.click()
    │           └─ file.text() → JSON.parse() → editor.fromJSON()
    │
    ├─ Save → editor.toJSON() → Blob → editor.utils.save()
    │
    ├─ Import → fileInput.click()
    │             └─ editor.loader.loadFiles()
    │
    └─ Export (submenu)
           ├─ DRC → DRACOExporter → saveArrayBuffer()
           ├─ GLB → GLTFExporter (binary) → saveArrayBuffer()
           ├─ GLTF → GLTFExporter (json) → saveString()
           ├─ OBJ → OBJExporter → saveString()
           ├─ PLY → PLYExporter → saveArrayBuffer()
           ├─ STL → STLExporter → saveString/saveArrayBuffer()
           └─ USDZ → USDZExporter → saveArrayBuffer()

Helper:
    └─ getAnimations(scene) → scene.traverse() → object.animations
```

### データフロー図

```
[入力]               [処理]                    [出力]

Open ────────────▶ file.text() ──────────────▶ JSON.parse()
                                                  │
                                                  ▼
                                            editor.fromJSON()
                                                  │
                                                  ▼
                                            シーン復元
                                            signals発火

Save ────────────▶ editor.toJSON() ──────────▶ JSON.stringify()
                                                  │
                                                  ▼
                                            new Blob()
                                                  │
                                                  ▼
                                            editor.utils.save()
                                                  │
                                                  ▼
                                            project.json ダウンロード

Import ──────────▶ editor.loader.loadFiles() ─▶ 各種Loader
                                                  │
                                                  ▼
                                            シーンにオブジェクト追加

Export GLB ──────▶ GLTFExporter.parse() ─────▶ ArrayBuffer
                        │                         │
                        ▼                         ▼
                   getAnimations()           saveArrayBuffer()
                        │                         │
                        ▼                         ▼
                   optimize()               scene.glb ダウンロード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Menubar.File.js | `editor/js/Menubar.File.js` | ソース | Fileメニューメインコンポーネント |
| Editor.js | `editor/js/Editor.js` | ソース | toJSON/fromJSON/clear |
| Loader.js | `editor/js/Loader.js` | ソース | ファイルインポート |
| DRACOExporter.js | `three/addons/exporters/DRACOExporter.js` | ライブラリ | Draco圧縮エクスポート |
| GLTFExporter.js | `three/addons/exporters/GLTFExporter.js` | ライブラリ | glTF/GLBエクスポート |
| OBJExporter.js | `three/addons/exporters/OBJExporter.js` | ライブラリ | OBJエクスポート |
| PLYExporter.js | `three/addons/exporters/PLYExporter.js` | ライブラリ | PLYエクスポート |
| STLExporter.js | `three/addons/exporters/STLExporter.js` | ライブラリ | STLエクスポート |
| USDZExporter.js | `three/addons/exporters/USDZExporter.js` | ライブラリ | USDZエクスポート |
| FileLoader.js | `three/src/loaders/FileLoader.js` | ライブラリ | ファイル読み込み |
