# Ep.18 — Customizing 03: 네이밍 & 팀 템플릿

https://youtu.be/2-FuUHzUm1k


스튜디오 네이밍으로 고친 뒤, **한 번만 만들고 common 템플릿으로 재사용**하는 방법을 정리한 문서입니다.

## 1. 왜 필요한가

BipedPlus 기본 네이밍(`Skin_*`, `Ctrl_*`, `Bip001`)이 팀 규칙과 다르면 막히는 경우가 많습니다.
팀 규칙으로 바꿀 수 있고, **매번 Rename을 반복하지 않도록 템플릿으로 저장**하는 것이 핵심입니다.

## 2. 전체 파이프라인

![BipedPlus Naming & Template Pipeline](./pipeline.png)

## 3. 네이밍 변경 허용 범위 및 주의사항

| 구분 | 내용 |
|------|------|
| ✅ 변경 가능 | Biped 이름, Skin 본 이름 (엔진 bone name 일치 목적), Controller 접두사, Layer 표시 이름 |
| ⚠️ 주의 | Hierarchy / Constraint / Space가 깨지지 않게 **일괄 규칙**으로 변경 권장 |
| ❌ Fix Missing 생략 금지 | Rename 후 Fix Missing을 안 하면 Mirror / Picker / Reset 어긋남 |

## 4. Fix Missing — Rename 후에도 시스템이 따라오게

이름이 바뀌면 INFO에 기록된 예전 이름과 어긋나 **Missing**이 납니다.

| 개념 | 설명 |
|------|------|
| **Seed** | 이름이 바뀌어도 노드를 구별하기 위한 유니크한 주소값 |
| **Fix Missing** | Seed를 이용해 새 이름 노드를 다시 링크하는 기능 |

**절차**: Rig Info → Load → Missing 확인 → Fix Missing 실행 → Mirror 갱신 확인 → Ani Utils로 검증

## 5. 레이어 이름 커스터마이징

Layer 설정 → **Edit Name** → 팀/프로덕트명 프리셋 → 접두/접미 추가 → **Apply to Rename**
Hierarchy의 역할 분류는 유지하고, **표시 이름만** 팀에 맞춥니다.

## 6. common 템플릿으로 저장

| 단계 | 내용 |
|------|------|
| 1 | 모델링 씬 (또는 New File) |
| 2 | **Merge** — `common/BP_Human_Template.max`의 노드 모두 |
| 3 | BipedPlus **Scan** — INFO / 미러 등 유지 확인 |
| 4 | Figure / 비율 등 캐릭터별 조정 |
| 5 | 캐릭터 폴더에 저장 → 애니 팀 배포 (Player로 작업) |

```
공유_리깅/
├── character_A/
├── character_B/
└── common/
    └── BP_Human_Template.max   ← 네이밍·레이어·INFO까지 맞춘 마스터
```

## 7. Picker 예외

| | INFO / Ani Utils (Fix Missing 후) | Picker |
|--|-----------------------------------|--------|
| Rename 후 | 복구 가능 | **이름 기반**이라 레이아웃이 깨질 수 있음 |

**권장**: 네이밍·템플릿이 확정된 뒤 새 네이밍으로 Picker를 재구성하고 팀에 배포.
Picker 파일 위치는 BipedPlus **Setting** 옵션에서 확인.

## 8. 체크리스트

- [ ] 팀 bone / Ctrl / Layer 네이밍 규칙이 문서화되어 있다
- [ ] Rename 예제(또는 팀 스크립트)로 일괄 변경한다
- [ ] Rename 후 Fix Missing + Mirror / Reset 검증을 한다
- [ ] `common/` 템플릿 `.max`가 공유폴더에 있다
- [ ] 새 캐릭터는 Merge → Scan 절차를 쓴다
- [ ] Picker는 최종 네이밍 기준으로 재구성한다
- [ ] 애니 팀은 Player로 **동일 설치 파일**을 쓴다


### Example Rename Script (handle 2-pass)

Edit `NODE_RENAME_MAP` to match your team's rules. Run in Max Script Editor after Build.

```python
# -*- coding: utf-8 -*-
"""BipedPlus naming example (handle 2-pass, short version)"""

import pymxs
rt = pymxs.runtime

NODE_RENAME_MAP = [
    ("Bip001",          "Bip009"),
    ("Bip001 Pelvis",   "Bip009 Pelvis"),
    ("Ctrl_Head",       "CTL_Head"),
    ("Skin_Spine1",     "Bip001_Spine1"),
    ("Skin_L_Hand",     "Bip001_L_Hand"),
]

def rename_nodes_by_handle(rename_map=None):
    mapping = rename_map if rename_map is not None else NODE_RENAME_MAP
    if not mapping:
        raise ValueError("NODE_RENAME_MAP is empty.")

    # Phase 1 — collect handles
    collected = []
    for src, dst in mapping:
        node = rt.getNodeByName(src)
        if node is None:
            print(f"[SKIP] {src}")
            continue
        collected.append((int(node.handle), src, dst))

    if not collected:
        raise ValueError("No rename targets found in scene.")

    # Phase 2 — apply
    for handle, src, dst in collected:
        node = rt.maxOps.getNodeByHandle(handle)
        if node is None:
            raise RuntimeError(f"handle={handle} restore failed ({src} → {dst})")
        node.name = dst
        print(f"[OK] {src} → {dst}")

    print(f"Done ({len(collected)} ok). Next: Rig Info → Fix Missing")

if __name__ == "__main__":
    rename_nodes_by_handle()
```

> After running: Rig Info → Fix Missing → verify Mirror / Reset.