# 機能設計書 79-LineSegments

## 概要

本ドキュメントは、Three.jsライブラリにおけるLineSegments（複数の線分）機能の設計を記述する。LineSegmentsは頂点のペアごとに独立した線分を描画するクラスであり、連続していない複数の線分を効率的に描画する。

### 本機能の処理概要

LineSegmentsは、Lineクラスを継承し、頂点データを2頂点ずつペアとして扱い、個別の線分を描画する。Lineが連続した線（LINE_STRIP）を描画するのに対し、LineSegmentsは独立した線分（LINES）を描画する。ワイヤーフレームジオメトリやエッジ表示などに使用される。

**業務上の目的・背景**：3Dグラフィックスにおいて、連続しない複数の線分を描画する必要がある場面は多い。メッシュのエッジ表示、座標軸の可視化、境界線の描画などでは、独立した線分を効率的に描画する機能が求められる。LineSegmentsは、このような用途に特化したクラスを提供する。

**機能の利用シーン**：ワイヤーフレーム表示（WireframeGeometry使用）、メッシュのエッジ表示（EdgesGeometry使用）、座標軸やグリッドの描画、デバッグ用の境界表示、CAD/BIMアプリケーションでのエッジ可視化。

**主要な処理内容**：
1. 頂点ペアを独立した線分として描画
2. Lineクラスの機能を継承（レイキャスト、モーフターゲット等）
3. 破線描画用の距離計算（computeLineDistances）をペア単位で実行

**関連システム・外部連携**：WebGLRenderer/WebGPURenderer、WireframeGeometry、EdgesGeometry、LineBasicMaterial、LineDashedMaterial。

**権限による制御**：特になし。

## 関連画面

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

## 機能種別

3Dオブジェクト生成 / 線分描画

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| geometry | BufferGeometry | No | 線分のジオメトリ | BufferGeometry型 |
| material | Material/Array<Material> | No | 線分のマテリアル | Material型または配列 |

### 入力データソース

JavaScriptコードからのコンストラクタ呼び出し。通常、WireframeGeometryやEdgesGeometryと組み合わせて使用される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isLineSegments | boolean | 型識別フラグ（常にtrue） |
| type | string | オブジェクト種別（'LineSegments'） |
| geometry | BufferGeometry | 線分のジオメトリ（継承） |
| material | Material/Array<Material> | 線分のマテリアル（継承） |

### 出力先

3Dシーングラフ、WebGLレンダリングパイプライン

## 処理フロー

### 処理シーケンス

```
1. コンストラクタ呼び出し
   └─ Lineの初期化
   └─ isLineSegments = true
   └─ type = 'LineSegments'
2. computeLineDistances() - 破線用距離計算（オーバーライド）
   └─ 2頂点ペアごとに距離を計算
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Lineコンストラクタ]
    B --> C[isLineSegments = true]
    C --> D[type = 'LineSegments']
    D --> E[終了]

    F[computeLineDistances] --> G{インデックス付き?}
    G -->|No| H[2頂点ペアごとに距離計算]
    G -->|Yes| I[警告を出力]
    H --> J[lineDistance属性を設定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-79-1 | ペア単位描画 | 頂点0-1、2-3、4-5...のペアで線分を描画 | 常時 |
| BR-79-2 | 偶数頂点推奨 | 頂点数は偶数であることが推奨される | 常時 |
| BR-79-3 | step=2 | レイキャスト時にstep=2で処理される | raycast時 |

### 計算ロジック

**破線用距離計算（ペア単位）**：
```javascript
for (let i = 0; i < positionAttribute.count; i += 2) {
    _start.fromBufferAttribute(positionAttribute, i);
    _end.fromBufferAttribute(positionAttribute, i + 1);

    lineDistances[i] = (i === 0) ? 0 : lineDistances[i - 1];
    lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end);
}
```

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 警告 | インデックス付きジオメトリでcomputeLineDistances | 非インデックスジオメトリを使用 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- GL_LINES相当の描画で効率的に処理される
- 頂点数に比例して処理時間が増加

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

特になし。

## 備考

- LineSegmentsはGL_LINES相当の描画を行う
- WireframeGeometryと組み合わせてワイヤーフレーム表示
- EdgesGeometryと組み合わせてエッジ表示
- レイキャストでは親クラスLineのraycastがstep=2で動作

---

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

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

### 推奨読解順序

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

LineSegmentsはLineを継承しているため、まずLineの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Line.js | `src/objects/Line.js` | 基底クラスの構造 |

**読解のコツ**: LineSegmentsはLineのほぼすべての機能を継承し、typeとcomputeLineDistancesのみをオーバーライドする。

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

LineSegmentsクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LineSegments.js | `src/objects/LineSegments.js` | クラス全体の構造 |

**主要処理フロー**:
1. **22-24行目**: コンストラクタでLineを初期化
2. **33行目**: isLineSegmentsフラグの設定
3. **35行目**: typeを'LineSegments'に設定

#### Step 3: computeLineDistancesを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LineSegments.js | `src/objects/LineSegments.js` | computeLineDistances()（39-70行目） |

**主要処理フロー**:
- **45-46行目**: インデックスなしチェック
- **50-57行目**: 2頂点ペアごとの距離計算
- **60行目**: lineDistance属性として設定

#### Step 4: レイキャスト処理を理解する

LineSegmentsはLineのraycastを継承し、isLineSegments=trueによりstep=2で動作する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Line.js | `src/objects/Line.js` | raycast()（185行目: step = this.isLineSegments ? 2 : 1） |

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

```
LineSegments
    │
    ├─ extends Line
    │      │
    │      ├─ extends Object3D
    │      │      └─ extends EventDispatcher
    │      │
    │      ├─ raycast() - step=2で動作
    │      └─ updateMorphTargets()
    │
    └─ computeLineDistances() - オーバーライド
           └─ 2頂点ペアごとの距離計算
```

### データフロー図

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

geometry (引数) ──────────────▶ Lineコンストラクタ ─────────────▶ this.geometry
material (引数) ──────────────▶ Lineコンストラクタ ─────────────▶ this.material

頂点データ (2頂点ペア)
[0,1], [2,3], [4,5]... ───────▶ GL_LINES描画 ──────────────────▶ 独立した線分

computeLineDistances()
positions[i], positions[i+1] ─▶ ペア距離計算 ──────────────────▶ lineDistance属性
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LineSegments.js | `src/objects/LineSegments.js` | ソース | 線分クラス |
| Line.js | `src/objects/Line.js` | ソース | 基底クラス |
| Object3D.js | `src/core/Object3D.js` | ソース | オブジェクト基底クラス |
| WireframeGeometry.js | `src/geometries/WireframeGeometry.js` | ソース | ワイヤーフレーム用ジオメトリ |
| EdgesGeometry.js | `src/geometries/EdgesGeometry.js` | ソース | エッジ用ジオメトリ |
| LineBasicMaterial.js | `src/materials/LineBasicMaterial.js` | ソース | 基本線マテリアル |
| LineDashedMaterial.js | `src/materials/LineDashedMaterial.js` | ソース | 破線マテリアル |
