# 開発ステップ (Development Steps)

## 全体方針 (Overall Policy)

実装は **核計算ロジックから外側に向かって積み上げる**：

1. **数値計算（評価指標）** が先．既知のテストデータで動作する状態を作る
2. **入力スキーマと I/O** を整える
3. **シーン構築 → 最小レンダー** で物理シミュレーションを動かす
4. **CLI として 2 段階パイプラインを完成**
5. **基準設計でキャリブレーション**
6. **設計バリエーションを比較**

各ステップ完了時に [GUIDE_04](../01_GUIDE/GUIDE_04_Git運用ルール.md) に従ってコミット・PR を作成する．`/implement <ステップ>` でコーディング → テスト → リファクタの自動パイプラインを通す．

## ステップ一覧 (Steps)

| Step | 名前 | 成果物 | 依存 |
| --- | --- | --- | --- |
| 1 | 均一性評価モジュールの移植 | `uniformity.py`, `evaluation/zones.py`, `evaluation/radial.py` + テスト | なし |
| 2 | YAML スキーマ定義 | `scene/schema.py` + バリデーションテスト | Step 1 |
| 3 | ジオメトリ層 | `geometry/loader.py`, `geometry/transforms.py` + テスト | Step 2 |
| 4 | シーン構築 + 最小レンダー | `scene/builder.py`, `scene/lights.py`, `scene/materials.py`, `scene/sensors.py`, `render/runner.py`, `render/output.py` | Step 3 |
| 5 | render CLI | `cli/render.py` + 統合テスト | Step 4 |
| 6 | evaluate CLI + 可視化 | `cli/evaluate.py`, `evaluation/roi.py`, `evaluation/visualize.py` | Step 1, 5 |
| 7 | 3D 照度ビューア（キャリブ調査ツール） | `visualize/baker.py`, `visualize/viewer.py`, `cli/visualize.py` | Step 4, 5 |
| 8 | 基準設計のキャリブレーション | `configs/scene_baseline.yaml`, `configs/meshes/*.stl`, キャリブ報告 | Step 5, 6, 7 |
| 9 | 設計バリエーション比較 | バリエーション YAML 複数 + 比較レポート | Step 8 |

## 人間の確認ポイント (Human Checkpoints)

各ステップは `/implement <Step>` で実装する．`/implement` 内の確認ポイント
（[GUIDE_05](../01_GUIDE/GUIDE_05_エージェント運用ルール.md) 準拠）に加え，Step 固有の人間関与は以下のとおり．

| Step | 事前準備（人間） | Phase 1 後の確認 | Step 完了の判断 |
| --- | --- | --- | --- |
| 1〜3 | なし | テスト結果の目視 | テスト全通過 |
| 4 | なし | **レンダリング PNG の目視確認**（光が物理的に妥当か） | 最小シーンが完走 |
| 5 | なし | CLI 入出力の確認 | コマンドが期待動作 |
| 6 | MiniTias-Evaluation の実測 PNG | **実測と評価結果の数値一致を確認** | 既知値と一致 |
| **7** | なし | **sm-visualize の 3D 表示確認（LED 位置・照度分布の目視）** | minimal scene で照度分布が解析解と数 % 以内 |
| **8** | **Fusion 360 → STL，LED 配置，材料初期値** | **実測との突合．パラメータ調整判断**（反復） | **許容範囲内で一致．数値を本ファイルに記録** |
| **9** | **改良案の Fusion 360 → STL（複数）** | **各バリエーションの結果評価と採用候補の選定** | **比較表完成．最低 1 案がベースライン改善** |

人間の本格的な介入は Step 7 以降．それ以前は AI 主導で進められる．

## 各ステップの詳細

### Step 1: 均一性評価モジュールの移植

- **目的**: 評価ロジックを最初に確定．ステップ 7 で「実測との比較」をするための物差しを先に作る
- **やること**:
  - `MiniTias-Evaluation/src/uniformity.py` を `src/sm_tias_lightsim/uniformity.py` にコピー
  - 元の SHA を docstring に明記（取得元: `https://github.com/rintoHasegawa/MiniTias-Evaluation`）
  - `evaluation/zones.py`：3 ゾーン分析（中心 d<0.33 / 中間 / 周辺 d≥0.66）
  - `evaluation/radial.py`：放射状プロファイル
  - テスト：合成輝度マップ（既知の CoV）に対して期待値が出ること
- **完了条件**: `uv run pytest tests/test_uniformity.py` が通る

### Step 2: YAML スキーマ定義

- **目的**: 設計ファイルの形式を確定し，不正入力を早期に弾く
- **やること**:
  - 依存追加: `uv add pydantic pyyaml`
  - `scene/schema.py`：[SPEC_02_シーン定義仕様](../04_SPEC/SPEC_02_シーン定義仕様.md) のトップレベル構造を Pydantic モデルで定義
  - 参照整合性チェック（meshes が存在しない materials を参照していないか等）
  - YAML loader（PyYAML）でファイル → dict → Pydantic model
  - テスト：正常 YAML がパースできる／不正 YAML が `ValidationError` を投げる
- **完了条件**: 各種異常系（必須欠落・型違反・参照不整合）でテストが通る

### Step 3: ジオメトリ層

- **目的**: STL を Mitsuba が扱える単位・座標系で読めるようにする
- **やること**:
  - `geometry/loader.py`：trimesh で STL 読込．頂点・面・単位タグを保持
  - `geometry/transforms.py`：mm → m 変換等
  - テスト：単位変換が可逆／簡単な四面体 STL を読み頂点数が一致する
- **完了条件**: テストフィクスチャの STL が正しく読める

### Step 4: シーン構築 + 最小レンダー

- **目的**: 実物のシミュレーションが動く最小構成を作る
- **やること**:
  - `scene/lights.py`：YAML 光源定義 → Mitsuba emitter
  - `scene/materials.py`：YAML 材料 → Mitsuba BSDF
  - `scene/sensors.py`：YAML センサ → Mitsuba sensor
  - `scene/builder.py`：上記を統合．YAML 全体 → Mitsuba scene dict
  - `render/runner.py`：variant 設定 + `mi.render` 実行．輝度配列を返す
  - `render/output.py`：HDR 配列 → PNG / `luminance.npy` 出力
  - 最小シーン（1 LED + 白板 + センサ）でレンダリングが成功すること
  - テスト：scene dict 構造の正しさ，最小レンダーの smoke test（`@pytest.mark.slow`）
- **完了条件**: 64×64 程度の合成シーンを最後までレンダリングできる

### Step 5: render CLI

- **目的**: コマンドラインから 1 行でシミュレーションを動かす
- **やること**:
  - `cli/render.py`：`sm-render --scene <yaml> --output <dir>` を実装
  - `pyproject.toml` の `[project.scripts]` に登録（`sm-render = "sm_tias_lightsim.cli.render:main"`）
  - テスト: 1 LED + 白板の最小シーン YAML から PNG が生成されること
- **完了条件**: `uv run sm-render --scene tests/fixtures/minimal.yaml --output /tmp/test/` が動く

### Step 6: evaluate CLI + 可視化

- **目的**: シミュ画像と実測画像の両方に同じ評価コマンドを使える状態にする
- **やること**:
  - `evaluation/roi.py`：`image_pixel` 型 ROI 抽出（最初は矩形のみ．`scene_face` は後回し可）
  - `evaluation/visualize.py`：輝度マップ / ヒストグラム / 放射プロファイル / ゾーンマップを matplotlib で出力
  - `cli/evaluate.py`：`sm-evaluate --image <png> --config <yaml> --output <dir>` を実装
  - テスト: 実測 PNG（MiniTias-Evaluation サンプル）と既知の指標値が一致すること
- **完了条件**: シミュ PNG と実測 PNG の両方で同じ指標 CSV が出る

### Step 7: 3D 照度ビューア（キャリブ調査ツール）

- **目的**: Step 8 のキャリブレーション作業で「実測と合わない」原因を 3D 視認で切り分けられるようにする．LED 配置・材料・ジオメトリのミスを評価板の数値だけでなく筐体内の照度分布として観察できる
- **やること**:
  - 依存追加: `uv add pyvista`
  - `visualize/baker.py`：直接照度ベイク（各 face 中心 → emitter への shadow ray + cosine 項 + 距離減衰）
  - `visualize/viewer.py`：PyVista プロッタ（メッシュ着色 + LED 球/矢印 + センサ視錐台 + 座標軸）
  - `cli/visualize.py`：`sm-visualize` CLI
  - テスト：解析解（I·cosθ/r²）との一致 + 遮蔽 shadow ray + screenshot smoke test
- **完了条件**: minimal scene で `sm-visualize` がインタラクティブウィンドウを開き，評価板の照度分布が解析解と数 % 以内で一致する

### Step 8: 基準設計のキャリブレーション

- **目的**: シミュレーションの妥当性を実測値で検証．以降の改良案の基準を作る
- **やること**:
  - 現行 MiniTIAS のジオメトリを Fusion 360 から STL でエクスポート
  - LED の配置（位置・向き・個数）を `configs/scene_baseline.yaml` に記述
  - 材料パラメータの初期値を仮置き（ディフューザー透過率・筐体内壁反射率）
  - `sm-render → sm-evaluate` で指標を算出
  - 実測値（CoV ≈ 0.0426, 中心/周辺比 ≈ 1.064, 勾配 ≈ 6%）と比較
  - 差分が大きい場合は SPEC_01 の「キャリブレーション戦略」順で原因切り分け
  - 一致したら **許容範囲を確定**：
    - 仮置き目標：CoV ±0.005，中心/周辺比 ±0.02，勾配 ±1.5%
    - データを見て調整．確定値を本ファイルの末尾に追記
- **完了条件**: 実測値と仮置き許容範囲内で一致．数値を本ファイルに記録

### Step 9: 設計バリエーション比較

- **目的**: 改良案を複数試して，実装に進む候補を絞る
- **やること**:
  - LED 個数・配置を変えた YAML を 3〜5 パターン作成（例: リング 4 → 6 → 8 個）
  - ディフューザー散乱パラメータを変えた YAML を 2〜3 パターン作成
  - 各パターンを `sm-render → sm-evaluate` で評価
  - 比較表（pandas DataFrame → CSV / Markdown）を生成
  - 有望な候補を Fusion 360 へフィードバック
- **完了条件**: 比較表が生成され，最低 1 つの改良案がベースラインより CoV 低下を達成

## キャリブレーション目標値（暫定）

Step 7 で実数値を見てから確定する．それまでの仮置き：

| 指標 | 実測値（参考） | 仮置き許容範囲 |
| --- | --- | --- |
| CoV | 0.0426 | ±0.005 |
| 中心/周辺比 | 1.064 | ±0.02 |
| 勾配 (%) | 6.23 | ±1.5 |

確定値は Step 7 完了時に本表を上書きする．

## マイルストーン (Milestones)

- **M1（Step 1〜2 完了）**: 評価ロジック + スキーマが動く．まだ実物シミュは動かない
- **M2（Step 4〜5 完了）**: シミュレーションの 1 周（YAML → PNG）が動く
- **M3（Step 6 完了）**: シミュ・実測の同一評価パイプラインが完成
- **M4（Step 8 完了）**: 基準設計と実測の整合が取れた．ここまでが「環境完成」
- **M5（Step 9）**: 改良案が複数比較できる．プロジェクトの本来目的を達成

## 将来検討事項 (Future Considerations)

### Step 10 候補: Blender + bpy アドオン版（GUI 強化）

**現時点では未着手．Step 9 完了後に必要性を判断する．**

#### 動機

現行の Mitsuba 版は YAML 手書き + CLI 駆動が中心で，「光源配置を試行錯誤する」「結果を直感的に確認する」操作性は弱い．Step 7 で PyVista 3D ビューアを入れたが，これは結果の確認に限る．**LED の配置・形状・配光プロファイル自体を GUI で試したい段階**になったら Blender アドオン版を別パッケージとして追加する．

#### 役割分担の見立て

| 層 | Blender + bpy 版での担当 |
| --- | --- |
| 3D 表示・LED 配置・マテリアル編集 | Blender 標準 GUI |
| 物理レンダリング | Cycles（モンテカルロパストレース） |
| 評価指標（CoV / 3 ゾーン / 放射プロファイル / ROI） | **現行の `uniformity.py`, `evaluation/*.py` を import で再利用** |
| 評価結果の表示 | 自作の `bpy.types.Panel`（Blender サイドバーに CoV 等を表示） |
| 配光プロファイル | IES ファイル直接読込（Blender 標準サポート） |

#### Cycles を採用する利点

- **GUI 操作性**: 3D ビューでのドラッグ配置・ノードベースのマテリアル編集．設計試行錯誤の速度が桁違い
- **IES 配光ファイル対応**: LED メーカー実測配光（CREE / OSRAM 等の `.ies`）をそのまま読み込める．Mitsuba 版では自作実装が必要
- **任意形状エミッタ**: Emission BSDF + ノードグラフで任意の配光関数を表現可能（Mitsuba の固定 emitter type より柔軟）
- **ぐりぐり回せる 3D ビュー**: PyVista 自作分が不要に

#### Mitsuba 版を残す理由

- **物理量の正確性**: Cycles は Watt 単位の解釈や View Transform の影響を受ける．Mitsuba は標準で W/m² を素直に返す → **キャリブレーションの真値生成は Mitsuba で行う**
- **CI / 自動テスト**: pytest で素直に回る．Blender ヘッドレス CI はやや手間
- **軽量さ**: Python パッケージのみで完結．Blender 本体（数百 MB）に依存しない

#### キャリブレーション戦略（Mitsuba ↔ Cycles 整合）

Cycles の `Light.energy`（W）と評価面の実 lx の対応は，**Mitsuba 版の Step 8 で確定した数値を真値として 1 回校正する**．具体的には：

1. Step 8 で確定した基準設計 YAML と同じシーンを Blender でも再現
2. 同じ評価面で CoV / 中心-周辺比を測定
3. Mitsuba 結果と一致するように Cycles の Light Energy・View Transform（Standard 推奨）・Color Management を調整
4. 「Mitsuba 1.0 W ≈ Cycles X W」の換算係数を Step 10 のドキュメントに記録

これで以降は Blender 版でも物理的に妥当な数値が出る．

#### 想定パッケージ構成

```
src/sm_tias_lightsim/             # 現行（Python パッケージ）
src/sm_tias_lightsim_blender/     # Step 10 候補（Blender アドオン）
  ├── __init__.py                  # bpy.types.AddonPreferences 登録
  ├── panels.py                    # サイドバー UI（評価ボタン・CoV 表示）
  ├── operators.py                 # 「評価実行」「YAML エクスポート」等
  └── render_runner.py             # Cycles 起動 + 結果取得
```

評価層（`uniformity.py`, `evaluation/*.py`）は Mitsuba に非依存なので **コード変更なしで再利用** できる．

#### 判断タイミング

Step 9 完了時点で以下を確認して着手判断する:

- 自分以外のメンバーがツールを触る必要が出てきたか
- LED 配置・配光の試行錯誤頻度が高く，YAML 手書きが律速になっているか
- IES 配光ファイルでの精密モデル化が必要になったか

いずれも該当しないなら Mitsuba 版で運用継続．
