# Get Nodes（取得 API）

右クリック Select メニューの通常 7 項目（`[Debug]` を除く）に対応する**取得専用 API**です。動詞は `get` で、主な目的はハンドル／名前の取得です。`select=1` のときだけ副作用としてシーン選択を行います（デフォルト `select=0` = 取得のみ、シーン選択は変更しません）。

---

## メソッド一覧

| メソッド | 右クリックメニュー | データソース |
| --- | --- | --- |
| `get_all_objects(slot, select=0)` | All Objects | リファレンス全ノードハンドル |
| `get_skin_meshes(slot, select=0)` | Skin Meshes | スキンメッシュハンドル |
| `get_skin_bones(slot, select=0)` | Skin Bones | スキンボーンハンドル |
| `get_all_skin_objects(slot, select=0)` | All Skin Objects | メッシュ + ボーン（重複除去、メッシュ優先） |
| `get_duplicate_nodes(slot, select=0)` | Duplicate Nodes | 名前が重複しているノードのみ |
| `get_biped_com(slot, select=0)` | Biped COM | Biped COM ノードハンドル |
| `get_biped_nodes(slot, select=0)` | Biped Nodes | Biped 全ノードハンドル |

---

## 共通パラメータ

| パラメータ | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| `slot` | `int` | ○ | スロット番号（0～9）。**bool/str/float は即 `TypeError`** |
| `select` | `int` (0/1) または `bool` | ×（既定 `0`） | `0`=取得のみ、`1`=取得後にシーン選択。`False`→`0`、`True`→`1`。それ以外は即 `ValueError` |

```text
select=0（既定） → 取得のみ。シーン選択は変更しない。
select=1         → 取得後、返却 handles で Max シーン選択まで行う。
```

---

## 共通戻り値契約

```python
{
    "success": True,
    "slot": 0,
    "category": "skin_meshes",
    "count": 12,
    "handles": [101, 102, ...],
    "names": ["Mesh_A", ...],
    "selected": 0,
    "selected_count": 0,
    "message": "skin_meshes: 12개",
}
```

| メソッド | `category` | 追加フィールド |
| --- | --- | --- |
| `get_all_objects` | `"all_objects"` | `reference_name` |
| `get_skin_meshes` | `"skin_meshes"` | — |
| `get_skin_bones` | `"skin_bones"` | — |
| `get_all_skin_objects` | `"all_skin_objects"` | — |
| `get_duplicate_nodes` | `"duplicate_nodes"` | `duplicate_names` (`list[str]`) |
| `get_biped_com` | `"biped_com"` | — |
| `get_biped_nodes` | `"biped_nodes"` | — |

---

## 空結果と有効ハンドルの再収集

- 保存ハンドルがない、またはすべて無効（削除済み）→ `success=True`、`count=0`、`handles=[]`、`names=[]`（**エラーではない**）。
- 重複がなければ `get_duplicate_nodes` は `duplicate_names=[]`、`count=0`。
- `select=1` でも選択対象がなければ `selected_count=0`（エラーではない）。
- 返却される `handles`/`names`/`count` は**現在シーンに存在する有効ノードのみ**で再収集される。

---

## 例外処理（FAIL FAST）

| 状況 | 例外 |
| --- | --- |
| `slot` が `int` でない（bool 含む） | `TypeError` |
| `slot` が範囲外／空スロット（リファレンス未ロード） | `ValueError` |
| `select` が 0/1/bool 以外 | `ValueError` |

不正な `slot`/`select` は `{"success": False}` ではなく**例外**として直ちに表面化します。

---

## 削除された select_* → get_* 置換

旧 `select_*` API は**完全削除**されました（shim なし）。`AttributeError` が出たら以下に置き換えてください。

| 削除済み | 代替 |
| --- | --- |
| `select_reference_nodes` | `get_all_objects(select=1)` |
| `select_duplicate_nodes` | `get_duplicate_nodes(select=1)` |
| `select_skin_mesh` | `get_skin_meshes(select=1)` |
| `select_skin_bones` | `get_skin_bones(select=1)` |

---

## 例

```python
from os_fast_ref.api import FastRefAPI

api = FastRefAPI()

# 取得のみ（シーン選択なし）
r = api.get_all_objects(slot=0)
print(r["reference_name"], r["names"])

# 取得 + シーン選択（右クリックメニューと同じ）
api.get_skin_meshes(slot=0, select=1)

# 重複名チェック（パイプライン向け — select=0 推奨）
dup = api.get_duplicate_nodes(slot=0)
if dup["duplicate_names"]:
    print("duplicates:", dup["duplicate_names"])
```

外部自動化では常に `FastRefAPI` を使ってください。semver 保証対象は `FastRefAPI` のみです。