
    NNjJ5                        d Z ddlZddlZddlZddlZddlmZ ej                  j                  d e
 ee      j                               ddlZddlZddlZej&                  dz  Zej*                  dz  ZdZddgZd	d
gZdj5                  g d      Zdj5                  g d      Zdj5                  g d      ZeedZd Zd Z dj5                  g d      Z!dj5                  g d      Z"d Z#d Z$d Z%d Z&d Z'd Z(e)dk(  rQ ejT                         Z+e+jY                  ddg d       e+jY                  dd !       e+jY                  d"d#!       e+j[                         Z.ej_                  dd$       e.j`                  jc                  d%      D  cg c]#  } | je                         s| je                         % c} Z0e.jf                  jc                  d%      D ch c]#  }|je                         s|je                         % c}Z4e.jj                  d&k(  r e$        ye.jj                  d'k(  r
 e&e0e4       ye.jj                  d(k(  r
 e'e0e4       y e(        yyc c} w c c}w ))u  s31 — 스테이징 우선 체인: 마네킹 구도 → bg+엔티티 합성 (2026-07-09, 커밋 금지).

s30(배경 플레이트 우선)과 대조되는 사용자 지시 체인:
  [1] mannequin — 샷 원문만 주고 t2i 가 카메라 구도를 '스스로' 잡는다
      (개입 없음 — 카메라/구도 지시 0). 두 형태 × i2/nb2 = 샷당 4장:
        sketch: 스토리보드 스케치, 사람=목제 마네킹
        photo : 실사 스테이징, 사람=회색 마네킹
  [2] compose — 최종샷: 스테이징(카메라·블로킹 SOT) + 최초 bg(장소·룩
      SOT, "bg 의 어느 지점인지" 명시=s30 grounding 존+앵커 서술명 재사용,
      ID-free) + passport 엔티티. 스테이징 소스(i2/nb2)×합성 엔진(i2/nb2)
      전 교차: A(sketch 유래) 4장 + B(photo 유래) 4장 = 샷당 8장.
대상=s30 선택 7샷 → 총 84장. 판정 지식: ID-free·발명 경계·철제 계단 정정.
사용: backend/.venv/bin/python s31_mannequin_first.py --only <stage>
      [--engines i2,nb2] [--shots S4_Shot1,...]   (병렬 분할용)
산출: out/mannequin_first/*.png + plans/s31_mannequin_v1.json
      + mannequin_first.html
    N)Pathmannequin_firstzmannequin_first.htmls31_mannequin_v1i2nb2sketchphoto
)zCYOU decide the camera: choose the angle, distance, height, lens andz?composition that best realise the shot text below. No camera oruD   composition instructions are given on purpose — stage it yourself.)zCDraw ONE storyboard frame for a live-action film shot: a monochromeuE   pencil production sketch on white paper — rough construction lines,zloose grey shading, no colour.zBEvery person in the frame appears as a featureless wooden artist'szAmannequin (jointed figure, no face, no hair, no clothing detail).z.If the shot text implies no people, draw none.)zBCreate ONE PHOTOREALISTIC staging photograph of a live-action filmz>shot on a real location set: the environment is fully real andzAphotographic, but every person in the frame is a featureless greyz8display mannequin (smooth blank head, no face, no hair).z1If the shot text implies no people, include none.)r   r	   c                 <   dd|j                  d       d|j                  d       g}|j                  d      r&|j                  ddj                  |d         z          d	j                  t        |    t        d
j                  |      t
        j                  g      S )Nz"SHOT TEXT (authoritative, Korean):zscene_heading: scene_headingzshot: description
characterszpeople in shot: , 

r
   )getappendjoin	FORM_HEADFREE_CAMERAS30NO_ANNOTATION)formsksliness       W/Users/manta/Documents/Projects/TheRoad-I1/scratchpad/forest_exp/s31_mannequin_first.py_mannequin_promptr   A   s    1quu_567aeeM*+,.E 	uu\'$))AlO*DDE;;	$dii6F))+ , ,    c                     | d   d   D ci c]  }|d   |d    }}|d   D cg c]  }||v s||    }}d|d    dd	j                  |      z   S c c}w c c}w )
uH   s30 grounding 존+앵커를 ID-free 서술로 (마커 코드 미노출).detailitemscodename_enanchor_markerszthe "map_zonez" area of the property, by the r   )r   )specgrounditc2ncnamess         r   _place_descr,   M   s    /3H~g/F
G/F2f:r)}$/FC
G#$45B5cSV5EBF:&''FGii   HBs   A	AA)zCCAMERA & BLOCKING: the FIRST attached image is the staging frame ofzBthis shot. Reproduce its camera (angle, distance, height, framing)z@and the exact placement and pose of every figure. Its drawing oru?   mannequin look is ONLY a staging aid — never carry its style,z(blankness or monochrome into the output.)z?LOCATION: the SECOND attached image is a real photograph of thez?entire filming property, and the single source of truth for howz=everything looks (building, materials, aging, colours, town).c                    |j                  d      xs g }dt        t        dt        | |       dz   d|j                  d      xs dz   d|j                  d	       z   g}|r'|j	                  d
dj                  |      z   dz          n|j	                  d       |j	                  d       |j	                  t        j                         |j	                  t        j                         dj                  |      S )Nr   zKCreate the FINAL photorealistic live-action film still of the moment below.z
This shot is taken at u~    — rebuild the surroundings seen by the staging camera from that exact spot of the property, consistent with the photograph.z MOMENT (authoritative, Korean): r    z
scene_heading: r   u}   CHARACTERS: replace each mannequin figure with the matching reference person, in the mannequin's exact position and pose — r   zi. Match each reference person's identity exactly (face, hair, build); dress them as the moment describes.z2No people appear unless the moment itself says so.uq   TIME & LIGHT: only as stated by the shot text above — do not add weather, atmosphere or colour moods beyond it.r   )	r   STAGING_NOTELOCATION_NOTE_HEADr,   r   r   r   WORLD_FACTSr   )r&   r   r   r'   charspartss         r   _compose_promptr4   d   s    EE,%2E	$[v%>$? @G G	G 	+aeeM.B.HbIaeeO45
6	7
E 99U+,/((	) 	IJ	LL   
LL!	LL""#;;ur   c                     t        j                  t        j                        } t        j                  t        j
                        }t	        j                         }|d   }|i i d}|D ]  }||   }t        D ci c]1  }|dt        |||      it        D ci c]  }|d| d| d| d c}3 c}}|d   |<   t        | |||d   |         }	|	t        | |d   |         t        D 
ci c]9  }t        D ].  }
t        D ]#  }| d|
 d	| d
|dk(  rdnd d| d| |
 d| d
% 0 ; c}}
}d|d   |<    t        j                  t
        |       t        dt        |       d       yc c}w c c}}w c c}}
}w )uS   전 프롬프트 결정·저장 (LLM 0, 이후 gen 스테이지는 png 만 쓴다).selected_shots)r6   	mannequincomposepromptmq__.pngr7   r'   _by_final_r   AB_by)r9   
place_descfilesr8   z
[prompts] u3   샷 × (마네킹 4 + 합성 8) 프롬프트 저장N)F	load_planS27SPECr   PLAN_load_shotsFORMSr   ENGINESr4   r,   	save_planprintlen)r&   s30shotsselplanr   r   r   engcpsrcs              r   stage_promptsrV      s   ;;sxx D
++chh
COOE

C!rBD"I !  8.tR; LBIJ'3cSat1SE66'JL L![" T2q#h-*;<%dCM",=> #(* #($7C!(#	 auD.dh&6sC@"$uCuD22 ")	 / 4; / #(*+Y  KKd	Js3xj S
TU K!*s   9E.E))E.)>E4)E.c                 |    | d   D cg c]
  }|r||v r| }}|t         D cg c]	  }||v s| c}fS c c}w c c}w )Nr6   )rK   )rR   enginesshots_filterkrQ   es         r   _targetsr\      sW    +, 5,!|"3 ,C 5G4GqqG|G44454s   4	99c                    t        j                  t              }t        || |      \  }}|D ]  }t        D ]  }|d   |   |   }|D ]\  }t
        ||   z  }	|dk(  r%t        j                  d| d| d|d   d d|	       9t        j                  d| d| d	|d   g d
|	       ^ t        d| d| ddj                  |       d         y )Nr7   r   s31_mq_r;   _i2r9   	1536x1024refssizeout_path_nb216:9aspect_ratiord   z[mannequin]  : +    완료)
rD   rE   rH   r\   rJ   OUTDimg_gptimg_nb2rM   r   )
rX   rY   rR   rQ   engsr   r   mrS   outs
             r   stage_mannequinrs      s    ;;tDw5ICD[!"%d+AQsVm$;IIvQrd#6(#'kCI IIvQrd$78b+1CA  LAdV2chhtn-=WEF  r   c                    t        j                  t              }t        j                         }t        j
                         }t        j                         d   }t        || |      \  }}t        j                  }|D ]d  }	|d   |	   }
||	   }|j                  d      xs g D cg c]A  }|j                  |      r.|j                  |j                  |            rd| d|||      fC }}t        D ]  }t        D ]  }t        |d   |	   |   |   z  }|j                         s
J d|        |D ]  }|
d   | d	| d
|    }t        |z  }|dk(  r<t        j                  d|d d  |
d   ||g|D cg c]  \  }}|	 c}}z   d|       ]d|fd|fg|z   }t        j                  d|d d  |
d   |d|          t!        d|	 ddj#                  |       d       g y c c}w c c}}w )Ncharacter_name_to_sidr8   r   u   CHARACTER REFERENCE — z5: the exact person who replaces one mannequin figure.r7   u   스테이징 없음: rC   r;   r=   r   s31_r9   r`   ra   uF   STAGING FRAME — camera & blocking source only; never copy its style.uX   LOCATION PHOTOGRAPH — the whole filming property; sole source of how everything looks.rf   rg   z
[compose] rj   rk   rl   )rD   rE   rH   r   rI   query_passports
load_reconr\   	PHOTO_PNGr   rJ   rK   rm   existsrn   ro   rM   r   )rX   rY   rR   rP   	passportsname_to_sidrQ   rp   bgr   r*   r   nppr   rU   stagingrS   fnrr   r;   prb   s                          r   stage_composer      sB   ;;tDOOE!!#I,,.!89Kw5IC	BOB"I l+1r1K1!#	kooa6H(I *! -( ()2;q>)BD1 	 K Dk!22!6t!<S!AA~~'J+@	)JJ'C7tfAcU$se$<=B)Cd{		DCR	"2AhK(/}b7Ibdab7I'I'2SB"@AH!J"+,.!0 1 46	 6
 		DCR	"2AhK/5E    & 	
2$b$ 0895 K 8Js   #AG$1G)c                     t        j                  t              } t        j                         }t        j                  t        j                        }d d+fd	d}| d   D ]  }||   }| d   |   | d   |   dj                  fdt        D              }d}dD ]1  \  dj                  fd	t        D              }|d
 d| z  }3 d}	|j                  d      xs i j                  |      xs i j                  d      }
|
r0t         j                  dz  |
z  j                         r d|
 d      }	t         j                  dz  dz  | dz  }|j                         r|	 d| dd      z  }	|d |       d |j                  d             d |j                  d             d j                  d             d| d| d|	 d d   d          d  d!   d          d  d          d"z  } d# d$d%d&       d| d'}t        j                  |d()       t        d*t                y ),Nc                 >    t        j                  t        |             S )N)_htmlescapestr)ts    r   esczstage_html.<locals>.esc   s    ||CF##r   c           
      .    d| d|  d|  d |       d	S )Nz<figure style='width:z%'><a href='z'><img src='z!' loading='lazy'></a><figcaption>z</figcaption></figure> )relcapwidthr   s      r   figzstage_html.<locals>.fig   s8    'wl3% @ E ""3xj(>@ 	Ar   r.   r6   r7   r8   c              3      K   | ]J  }t         D ]?  }t        |   |   z  j                         r  d |   |    |dk(  rdnd d|        A L yw)out/mannequin_first/r   u   ①스케치u	   ②실사u    마네킹 NrK   rm   r{   ).0r   rS   r   rq   s      r   	<genexpr>zstage_html.<locals>.<genexpr>   ss      / #qws|#++- &qws|n5%)X%5>;G{SVRWXZ)0Zs   AA))r   u   A(스케치 유래))r	   u   B(실사 유래)c           
   3      K   | ]P  }t         D ]E  } d | d| }t        d   |   z  j                         r dd   |     d| d|        G R yw)r;   r=   rC   r   z src=u    → 합성=Nr   )r   rU   rS   rZ   r*   r   r   labs       r   r   zstage_html.<locals>.<genexpr>   s      4 #Cgs!F!C5SE2A1W:a=(002	 *1W:a=/:e5\#79.59"s   AAz<h3>u    최종 4교차</h3>file
shot_applyzout/shot_apply/u.   비교: s30 최종(배경 플레이트 우선)baseliner<   zout/shot_apply/baseline/u    비교: 기존 production 스틸z
<h2>u    — r   z	</h2>
<p>r   u!   </p>
<p><b>bg 지점 명시</b>: rB   uE   </p>
<h3>① / ② 마네킹 스테이징 (카메라 t2i 재량)</h3>r
   u\   
<details><summary>프롬프트(마네킹 스케치/실사 · 합성 공통)</summary>
<pre>r   r9   z</pre>
<pre>r	   z</pre></details>
u  <!doctype html><html lang=ko><head><meta charset=utf-8>
<title>s31 — 스테이징 우선 체인 (마네킹 구도 → bg 합성)</title><style>
body{font-family:'Apple SD Gothic Neo',sans-serif;margin:24px;max-width:1500px}
figure{display:inline-block;margin:1%;vertical-align:top}
img{width:100%;border:1px solid #ccc} figcaption{font-size:13px;text-align:center}
pre{font-size:11px;background:#f7f7f7;border:1px solid #ddd;padding:8px;
white-space:pre-wrap;max-height:320px;overflow:auto}
h2{border-bottom:2px solid #333;padding-bottom:4px;margin-top:36px}
h3{margin:14px 0 4px}</style></head><body>
<h1>s31 — 스테이징 우선 체인 (2026-07-09)</h1>
<p>체인: [1] 샷 원문만으로 t2i 가 카메라 구도를 스스로 잡은 마네킹 스테이징
(①스케치/②실사 × i2/nb2) → [2] 스테이징(카메라·블로킹 SOT)+최초 bg(장소·룩
SOT, 지점 명시)+passport 로 최종 합성(소스×엔진 전 교차 8장/샷).
s30(배경 플레이트 우선)과 비교용.</p>
z,out/forest_map/top2/top2_photo_fixed_nb2.pngu   장소·룩 SOT — 최초 bg   z
</body></html>zutf-8)encodingz[html] )   )rD   rE   rH   r   rI   r   rJ   rK   r   OUTr{   PAGE
write_textrM   )rR   rP   rO   secsr   r   mfigsrowsffigss30cmps30fbasedocr*   r   r   r   r   rq   s                @@@@@@r   
stage_htmlr      s   ;;tDOOE
++chh
C$A
 D#$"Ib!OB / / /
 [ID#GG 4 #4 4E d3%3E7;;D \ #)r..r28b==fEQUU\)D088:?4&13cdFuu|#j0bT;>;;=c4RD=<> >F WIU3quu_-./ 0m  |!456 7AAF H  		!H+h
 ! "	!G*X
  !	!H+  	5 %N 35TVXY Z [ C" 	OOC'O*	GD6
r   __main__z--onlyT)promptsr7   r8   html)requiredchoicesz	--engineszi2,nb2)defaultz--shotsr.   )parentsexist_ok,r   r7   r8   )6__doc__argparser   r   jsonsyspathlibr   pathinsertr   __file__parent
forest_librD   s27_forest_maprF   s30_shot_applyr   r   rm   EXPr   rH   rK   rJ   r   r   MANNEQUIN_SKETCHMANNEQUIN_PHOTOr   r   r,   r/   r0   r4   rV   r\   rs   r   r   __name__ArgumentParserapadd_argument
parse_argsamkdirrX   splitstriprP   rY   only)r[   r   s   00r   <module>r      s@  "    
  3tH~,,- .   uu  uu%%-	7 ii   99    ))   (/B	,  yy   YY    @V45G"!:HGT z	 	 	 	"BOOHtG  IOOKO2OOIrO*
AJJtdJ+"#))//#"6D"6Q!'')qwwy"6DG'(ww}}S'9G'9!QWWYAGGI'9GLvv	
;	.	
9	g|,#  EGs   I$II,I