# 機能設計書 38-ExtrudeGeometry

## 概要

本ドキュメントはThree.jsにおける押し出しジオメトリ（ExtrudeGeometry）クラスの機能設計を記述する。ExtrudeGeometryはBufferGeometryを継承し、2Dシェイプを3D空間に押し出して立体形状を生成するジオメトリクラスである。

### 本機能の処理概要

ExtrudeGeometryは3Dグラフィックスにおいて2Dシェイプ（Shape）を奥行き方向に押し出して3Dメッシュを生成するためのジオメトリクラスである。ベベル（面取り）処理、パスに沿った押し出し、穴を含むシェイプの処理など、高度な機能を提供する。

**業務上の目的・背景**：3Dグラフィックスにおいて、ロゴ、テキスト、カスタム形状などの2D形状を3D化するニーズは非常に多い。建築のモールディング、製品のブランドロゴ、ゲームのUI要素など、押し出し形状は広く使用される。ExtrudeGeometryはこれらの形状を2Dシェイプから自動生成する。

**機能の利用シーン**：3Dテキストの生成、ロゴの3D化、建築モールディングの作成、カスタム形状の立体化、パスに沿った押し出し（パイプ、レール等）。

**主要な処理内容**：
1. Shape（2Dシェイプ）を受け取り、輪郭と穴を抽出
2. ShapeUtilsで三角形分割（Earcut アルゴリズム）
3. ベベル処理（オプション）で滑らかなエッジを生成
4. 深さ方向に押し出して側面を生成
5. オプションのextrudePathに沿った押し出し
6. UV座標を自動生成（カスタムUVGeneratorも可能）

**関連システム・外部連携**：レンダラー（WebGLRenderer、WebGPURenderer）と連携してメッシュを描画する。Shapeクラス、Curveクラス、ShapeUtilsと連携する。

**権限による制御**：特になし。全てのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに直接の関連なし |

## 機能種別

計算処理 / ジオメトリ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| shapes | Shape \| Array<Shape> | No | 押し出す2Dシェイプ | なし |
| options.curveSegments | number | No | 曲線の分割数（デフォルト: 12） | なし |
| options.steps | number | No | 深さ方向の分割数（デフォルト: 1） | なし |
| options.depth | number | No | 押し出す深さ（デフォルト: 1） | なし |
| options.bevelEnabled | boolean | No | ベベル処理を有効にするか（デフォルト: true） | なし |
| options.bevelThickness | number | No | ベベルの厚さ（デフォルト: 0.2） | なし |
| options.bevelSize | number | No | ベベルのサイズ（デフォルト: bevelThickness-0.1） | なし |
| options.bevelOffset | number | No | ベベルのオフセット（デフォルト: 0） | なし |
| options.bevelSegments | number | No | ベベルの分割数（デフォルト: 3） | なし |
| options.extrudePath | Curve | No | 押し出しパス（3D曲線） | なし |
| options.UVGenerator | Object | No | カスタムUV生成オブジェクト | なし |

### 入力データソース

コンストラクタ引数として直接指定される。Shapeは通常ShapeクラスやPathクラスで定義される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| position | Float32BufferAttribute | 頂点の3D位置座標 |
| normal | Float32BufferAttribute | 頂点の法線ベクトル（computeVertexNormalsで計算） |
| uv | Float32BufferAttribute | テクスチャマッピング用UV座標 |
| groups | Array | マテリアルグループ（蓋と側面で分離） |

### 出力先

BufferGeometry属性として保持され、Meshオブジェクトを通じてGPUに送信される。

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ shapes と options を受け取る
2. 各シェイプに対して addShape を実行
   └─ 輪郭と穴を抽出
3. 頂点の巻き方向を確認・修正
   └─ 反時計回りに統一
4. ベベル処理（オプション）
   └─ 面取り用の頂点を生成
5. 三角形分割
   └─ ShapeUtils.triangulateShape で面を生成
6. 側面の生成
   └─ sidewalls 関数で押し出し面を生成
7. 法線計算
   └─ computeVertexNormals で法線を自動計算
8. BufferGeometry属性を設定
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[shapes, optionsを受け取る]
    B --> C{複数シェイプ?}
    C -->|Yes| D[各シェイプに対してループ]
    C -->|No| E[単一シェイプ処理]
    D --> E
    E --> F[輪郭・穴を抽出]
    F --> G{extrudePath指定?}
    G -->|Yes| H[パスに沿って押し出し]
    G -->|No| I{bevelEnabled?}
    I -->|Yes| J[ベベル頂点生成]
    I -->|No| K[ベベルなし]
    H --> L[三角形分割]
    J --> L
    K --> L
    L --> M[蓋面を生成]
    M --> N[側面を生成]
    N --> O[computeVertexNormals]
    O --> P[属性設定]
    P --> Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-001 | 巻き方向 | 輪郭は反時計回り、穴は時計回りに統一 | 常時 |
| BR-38-002 | ベベル無効化 | extrudePath使用時はbevelEnabledがfalseに強制 | extrudePath指定時 |
| BR-38-003 | マテリアルグループ | 蓋（group 0）と側面（group 1）で分離 | 常時 |
| BR-38-004 | 重複点除去 | 近接点を自動的にマージ | 常時 |

### 計算ロジック

ベベル計算:
- bevelSize = bevelSize * sin(t * PI/2) + bevelOffset
- z = bevelThickness * cos(t * PI/2)

extrudePath使用時:
- Frenet-Serretフレームを計算
- 各頂点をフレームに沿って配置

## データベース操作仕様

該当なし（クライアントサイドのみで動作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | エラー | getBevelVecでvecがundefined | error関数でログ出力 |
| - | 警告 | 自己交差シェイプ | 結果が不正になる可能性 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- 頂点数はシェイプの複雑さ、depth、bevelSegments、stepsに依存
- 複雑なシェイプ（穴を含む）は三角形分割に時間がかかる
- 大きなベベル設定は頂点数を大幅に増加させる

## セキュリティ考慮事項

特になし（クライアントサイドのジオメトリ生成処理）

## 備考

- WorldUVGeneratorがデフォルトのUV生成器として使用される
- カスタムUVGeneratorを渡すことでUV座標を制御可能
- toJSON/fromJSONでシリアライズ・デシリアライズ可能

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

Shapeクラスと三角形分割の仕組みを理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Shape.js | `src/extras/core/Shape.js` | 2Dシェイプの定義方法 |
| 1-2 | ShapeUtils.js | `src/extras/ShapeUtils.js` | triangulateShape関数、isClockWise関数 |
| 1-3 | Earcut.js | `src/extras/Earcut.js` | 三角形分割アルゴリズム |

**読解のコツ**: ShapeはPathを継承し、穴（holes）を持つことができる。extractPointsでshapeとholesを分離して取得する。

#### Step 2: エントリーポイントを理解する

ExtrudeGeometryクラスのコンストラクタとaddShape関数が処理の起点。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ExtrudeGeometry.js | `src/geometries/ExtrudeGeometry.js` | コンストラクタとaddShape関数 |

**主要処理フロー**:
1. **40行目**: コンストラクタでshapes, optionsを受け取る
2. **58行目**: shapesを配列化
3. **65-69行目**: 各シェイプに対してaddShapeを呼び出し
4. **77行目**: computeVertexNormalsで法線計算

#### Step 3: addShape関数の詳細を理解する

押し出し処理の中核となるaddShape関数。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ExtrudeGeometry.js | `src/geometries/ExtrudeGeometry.js` | 81-749行目のaddShape関数 |

**主要処理フロー**:
- **87-99行目**: オプションの取得とデフォルト値設定
- **140行目**: shape.extractPointsで輪郭と穴を取得
- **145-165行目**: 巻き方向の確認と修正
- **236-357行目**: getBevelVec関数でベベル方向を計算
- **400-454行目**: ベベル頂点の生成
- **574-628行目**: buildLidFaces関数で蓋を生成
- **632-653行目**: buildSideFaces関数で側面を生成

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

```
ExtrudeGeometry.constructor()
    │
    ├─ BufferGeometry.constructor()
    │
    ├─ shapes配列化
    │
    └─ 各shapeに対してaddShape(shape)
           │
           ├─ オプション取得・デフォルト値設定
           │
           ├─ shape.extractPoints(curveSegments)
           │      ├─ vertices (輪郭)
           │      └─ holes (穴)
           │
           ├─ ShapeUtils.isClockWise() → 巻き方向確認
           │
           ├─ mergeOverlappingPoints() → 重複点除去
           │
           ├─ getBevelVec() → ベベル方向計算
           │
           ├─ ベベル頂点生成（bevelSegments分）
           │
           ├─ ShapeUtils.triangulateShape() → 三角形分割
           │
           ├─ buildLidFaces() → 蓋面生成
           │      └─ f3() → 三角形追加
           │
           └─ buildSideFaces() → 側面生成
                  └─ f4() → 四角形（2三角形）追加
```

### データフロー図

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

Shape ───────▶ ExtrudeGeometry ───▶ BufferGeometry
(輪郭+穴)          │                 (position,
                   │                  normal,
options ───────▶   │                  uv,
(depth,            ▼                  groups)
 bevel,       extractPoints
 etc.)             │
                   ▼
              isClockWise
              (巻き方向確認)
                   │
                   ▼
              triangulateShape
              (三角形分割)
                   │
                   ▼
              頂点生成
              (蓋+側面)
                   │
                   ▼
              computeVertexNormals
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ExtrudeGeometry.js | `src/geometries/ExtrudeGeometry.js` | ソース | 押し出しジオメトリクラス定義 |
| Shape.js | `src/extras/core/Shape.js` | ソース | 2Dシェイプ定義 |
| ShapeUtils.js | `src/extras/ShapeUtils.js` | ソース | 三角形分割、巻き方向判定 |
| Earcut.js | `src/extras/Earcut.js` | ソース | 三角形分割アルゴリズム |
| BufferGeometry.js | `src/core/BufferGeometry.js` | ソース | 基底クラス |
| Vector2.js | `src/math/Vector2.js` | ソース | 2Dベクトル |
| Vector3.js | `src/math/Vector3.js` | ソース | 3Dベクトル |
| Curves.js | `src/extras/curves/Curves.js` | ソース | extrudePathで使用する曲線 |
