리노컷 공통 파이프라인 캐스트 확장 — 정렬·정규화·얼굴 해칭·원화 눈썹·눈 실측
- register_edit(편집본 ECC 정렬·챔퍼 지표), normalize_base(P1 머리 크기 정규화, 위쪽 종이색 채움) - faceDetail region=face(얼굴 해칭을 원화 픽셀로 보존)·matchFacelessColor - brow_sprite 단계: 원화 눈썹 잉크 스프라이트(hairFront 아래 제외), 윗눈꺼풀 두께·홍채 실측 - 리그 계약 RigBrow.halfWidth/sprite·RigEye.lineScale, 렌더러 눈썹 16띠·바깥쪽 눈꺼풀 굵기 - 실행기 UTF-8 하위 실행, brow_centerline 패딩본 자체 생성, QA 시트 촬영 도구(깜빡임 회피·고해상도 대조) - P1은 새 필드를 모두 끄고 게시 자산·리그 바이트 동일
This commit is contained in:
parent
9a22d1647b
commit
98577cf4ae
18 changed files with 2524 additions and 85 deletions
|
|
@ -37,6 +37,7 @@ DEFAULT_BACKDROP = {
|
|||
"energy": "#E2E0D0",
|
||||
}
|
||||
DEFAULT_BUST_Y_OFFSET = 40.0
|
||||
DEFAULT_FACE_INSET_PX = 8.0
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -70,6 +71,32 @@ class PersonaConfig:
|
|||
# 단위 회귀가 성립한다. {"browLeft": {...}, "browRight": {...}} 형태(각
|
||||
# inner/peak/outer), manifest.landmarks.eyebrowLeft/Right와 같은 스키마.
|
||||
brow_landmarks_override: dict | None
|
||||
# false면 export_rig.py가 RigBrow.halfWidth를 쓰지 않는다(렌더러가 linocutGeometry.ts
|
||||
# BROW_STOPS 고정값을 쓴다). 기본 true — 원화에서 잰 눈썹 반두께(manifest.browCenterline.
|
||||
# halfWidth{Left,Right})를 쓴다. P1은 이미 고정 굵기로 빌드·검수됐으므로 false로 둔다.
|
||||
brow_half_width_from_art: bool
|
||||
# false면 brow_sprite.py가 눈썹 스프라이트(layers/v2/brow-{left,right}.png)를
|
||||
# 만들지 않는다(결정문 §8.4.1). 기본 true. P1은 이미 고정 벡터 눈썹으로
|
||||
# 빌드·검수됐으므로 false로 둔다.
|
||||
brow_sprite_from_art: bool
|
||||
# false면 brow_sprite.py가 눈꺼풀 선 굵기 배율(RigEye.lineScale)을 재지 않는다
|
||||
# (결정문 §8.4.1). 기본 true. P1은 lineScale의 기준값 자체(P1_UPPER_LID_THICKNESS_PX)라
|
||||
# false로 둔다.
|
||||
eye_line_scale_from_art: bool
|
||||
# false면 export_rig.py가 RigEye.iris에 manifest.landmarks(mediapipe)의 값을 그대로
|
||||
# 쓴다. 기본 true — brow_sprite.py가 원화에서 실측한 홍채(manifest.iris)를 쓴다
|
||||
# (2차 보정 T3: mediapipe iris 랜드마크는 실제 눈 비례로 학습돼 판화 잉크 홍채보다
|
||||
# 크게 잡는 경향이 있다). P1은 이미 고정 벡터 렌더로 빌드·검수됐으므로 false로 둔다.
|
||||
iris_from_art: bool
|
||||
# faceDetail.region: "features"(기본, 눈·입 주변 타원만) | "face"(얼굴 오벌 전체 —
|
||||
# 캐스트 확장, 얼굴 피부 해칭 보존). face_detail.py만 쓴다.
|
||||
face_detail_region: str
|
||||
# region="face"일 때 얼굴 오벌 경계에서 안쪽으로 줄이는 폭(px) — 원화 윤곽 잉크선이
|
||||
# 이 영역에 들어오지 않게 하는 여유. region="features"면 쓰이지 않는다.
|
||||
face_inset_px: float
|
||||
# true면 face_detail.py가 제외 영역(눈·눈썹·입) 안을 채우는 faceless(F) 픽셀의
|
||||
# 색을 주변 원화 피부에 맞춰 평행이동한다(보간/블러 없음). 기본 false(P1 그대로).
|
||||
match_faceless_color: bool
|
||||
|
||||
def require_pivots(self) -> dict:
|
||||
if self.pivots is None:
|
||||
|
|
@ -183,6 +210,18 @@ def load_persona_config(persona_dir: Path) -> PersonaConfig:
|
|||
face_detail = data.get("faceDetail", {})
|
||||
moles = face_detail.get("moles", [])
|
||||
brow_landmarks_override = face_detail.get("browLandmarksOverride")
|
||||
brow_half_width_from_art = data.get("browHalfWidthFromArt", True)
|
||||
brow_sprite_from_art = data.get("browSpriteFromArt", True)
|
||||
eye_line_scale_from_art = data.get("eyeLineScaleFromArt", True)
|
||||
iris_from_art = data.get("irisFromArt", True)
|
||||
face_detail_region = face_detail.get("region", "features")
|
||||
if face_detail_region not in ("features", "face"):
|
||||
raise SystemExit(
|
||||
f"[중단] {persona_dir.name}/persona.json의 faceDetail.region={face_detail_region!r}는 "
|
||||
"지원하지 않는다 — \"features\" 또는 \"face\"만 쓴다."
|
||||
)
|
||||
face_inset_px = float(face_detail.get("faceInsetPx", DEFAULT_FACE_INSET_PX))
|
||||
match_faceless_color = bool(face_detail.get("matchFacelessColor", False))
|
||||
|
||||
pivots = data.get("pivots")
|
||||
crops = data.get("crops", {})
|
||||
|
|
@ -211,4 +250,11 @@ def load_persona_config(persona_dir: Path) -> PersonaConfig:
|
|||
palette_fixed=palette_fixed,
|
||||
backdrop=backdrop,
|
||||
brow_landmarks_override=brow_landmarks_override,
|
||||
brow_half_width_from_art=bool(brow_half_width_from_art),
|
||||
brow_sprite_from_art=bool(brow_sprite_from_art),
|
||||
eye_line_scale_from_art=bool(eye_line_scale_from_art),
|
||||
iris_from_art=bool(iris_from_art),
|
||||
face_detail_region=face_detail_region,
|
||||
face_inset_px=face_inset_px,
|
||||
match_faceless_color=match_faceless_color,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue