
    gIj$+                        d 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dZd Zd Zd Zd	 Zd
 Zd Zedk(  r e        yy)u  s8 — 4라운드(사용자 재정의): 건물 전체 통합 도면 + 실외샷 1개(무마킹·무인).

사용자 의도(2026-07-05): 뿌리 = 옥탑방 레벨만이 아니라 **옥탑방이 얹힌 건물
전체** — 지상 출입구/마당(인물들이 도착하는 쪽), 외부 계단, 옥상 레벨 — 를
한 장의 top-down 도면으로. 그걸 기반으로 필요한 실외샷 하나를 카메라/엔티티
없는 빈 형태로 생성. 거기까지만.

기하 앵커 = 그룹의 실외 fp 전부(옥상 레벨 + 지상 마당 + 계단). 요소 선정은
LLM(전 샷 내용 원문), 시나리오 중립.
사용: .venv/bin/python s8_root_v2.py [--only plan|root|readback|shot]
산출: plans/root_plan_v2.json, out/root_v2/root_v2.png, out/outdoor_d/<sk>/
    N)Pathroot_v2u
  You are the master planner for a group of connected filming locations
(one real-world place: a building and its grounds, with indoor and outdoor parts).
You are given the place's member descriptions and the FULL content of every shot.

Design ONE comprehensive TOP-DOWN site plan of the WHOLE property — not just its
top level. The plan must show, together in one drawing:
- the full BUILDING footprint (the multi-storey building the upper dwelling sits on),
- the GROUND level around it: the yard/alley, the building's street-side entrance
  and the approach path where characters arrive,
- the exterior STAIR route connecting ground to the top level,
- the TOP level: the upper dwelling's roof outline, its terrace and fixtures,
- a modest margin of the immediate surroundings.

Select the elements to mark on this one plan. Hard rules:
- NEVER expose interior floor plans or interior furniture; enclosed spaces show
  only their outline and boundary openings (doors, windows, gates).
- Cover every shot: for each shot, the elements needed to locate its action.
- At most 12 elements, each with a single capital letter ID and a SHORT English
  name (1-3 words). Placement phrases must be relative and physical, grounded in
  the given data only. Generic physical terms, no proper names.c                 B   t        j                  | d         }dj                  d t        | d   j	                               D              }d|z   dz   |z   dz   }t        j
                  dt        |t        j                  d	
      }t        j                  d|       |j                  dg       D ch c]  }|d   	 }}t        dt        |d          dt        |       dt        | d                 |d   D ]   }t        d|d    d|d    d|d    d       " |S c c}w )Nmembersz

c              3   N   K   | ]  \  }}t        j                  ||        y wN)F
shot_block).0kss      s8_root_v2.py	<genexpr>zr1_v2.<locals>.<genexpr>1   s%      G'Etq!Q'Es   #%shotszPLACE MEMBERS:
z

ALL SHOTS AT THIS PLACE:

z6

Design the whole-property site plan element set now.forest_root_plan_v2gptmodelroot_plan_v2coverageshot_keyzR1v2: elementsz elements, coverage /z  (id) name_enz [category])r	   members_blockjoinsorteditemsllmR1V2_SYSTEMS1	R1_SCHEMA	save_plangetprintlen)reconr   shot_blocksuserplanccoveredes           r   r1_v2r2   /   s8   ooeI./G++ G'-eGn.B.B.D'EG GK(013>?HID 55&T2<<DKK%&*hhz2&>?&>q}&>G?	F3tJ'())=\N!Cg/02 3*AdG9Bq|nBq}oQ?@ K @s   /Dc                     g }| d   D ]E  }|d   r	| d   j                  |d         xs g D ]  }|j                  |d   |d   |d   f       ! G |S )uY   그룹 실외 loc 의 fp 전부 (레벨별 기하 앵커) — 데이터 순서 결정론.r   	is_indoor	fp_by_locloc_idfp_idpng_path)r(   append)r+   fpsmfps       r   exterior_fpsr=   A   sl    
C9[>%))!H+6<"<BJJ(R["Z.AB = 
 J    c                 <   t        |       }|st        d      dj                  d t        t	        |            D              }dj                  d |d   D              }dj                  d |d   D              }dj                  g dd	d
ddddddddddddddddd|ddt        j                  | d         dd|ddd|dd d!      }t        j                  d"||D cg c]  \  }}}|
 c}}t        d#z  $      S c c}}w )%Nzno exterior fps
c              3   .   K   | ]  }d |dz    d  yw)z- attached image #   zX: top-down plan of one part of the property (its geometry for that part is ground truth)N )r   is     r   r   zroot_v2.<locals>.<genexpr>P   s,      " !A QUG $8 	9 s   c              3   D   K   | ]  }d |d    d|d    d|d      yw)(r   r   r   u    — 	placementNrC   r   r1   s     r   r   zroot_v2.<locals>.<genexpr>T   s8      4"2Q QtWIR)~U1[>:JK"2s    r   z, c              3   R   K   | ]  }|d     d|d   j                           ! yw)r   : r   N)upperrH   s     r   r   zroot_v2.<locals>.<genexpr>V   s5      8&6 !"$y1Y<+=+=+?*@A&6s   %'z?ONE hand-drawn TOP-DOWN aerial SITE PLAN of a single real-worldzEproperty, seen straight from above: dark ink outlines with light flatz8colour washes. NOT a photograph, NOT 3D, no perspective. z0Draw the WHOLE property in one coherent drawing:zH- the full multi-storey BUILDING footprint (roof plane seen from above),zG- the upper-level dwelling on that roof: its outline, terrace, fixturesuD     (draw ONLY what its attached plan shows — never interior rooms),zB- the exterior STAIR route connecting the ground to the top level,zG- the GROUND level around the building: the yard/alley, the street-sidez>  building ENTRANCE and the approach path where people arrive,z<- a modest margin of neighbouring structures and the street.zEMake the levels readable from above: the building's roof edge/parapetzDoutline separates the top level from the ground around it; the stairzAvisibly connects them; the ground entrance sits on the building'szstreet side.uF   The attached images are the property's real top-down plans — composezFthem into this ONE plan, keeping each part's geometry, proportions andzBopening positions EXACTLY (do not move, resize, mirror or invent):zTHE PLACE (production data):r   zDMark each element with a small circle containing its capital letter:zGOn the RIGHT side, add a clean legend panel listing each circled letterz4with its English name in small neat capital letters:zAThe circled letters and the legend are the ONLY text and the ONLYzFcircular marks allowed. No zone captions, no numbers, no other labels.root_v2_whole_propertyroot_v2.pngrefsout_path)	r=   
SystemExitr    ranger*   r	   r   img_gptOUTR)	r+   r.   r:   	ref_linesel_lineslegend_linesprompt_ps	            r   r   r   L   sG   
u
C*++		 " s3x" "I yy 4"&z"24 4H99 8&*:&68 8LYY #I#O# 	C# 		#
 	;# 	S# 	R# 	O# 	M# 	R# 	I# 	G# 	P# 	O# 	L#  	!#" 	##$ 	Q%#& 	Q'#( 	M)#* 	+#, 	-#. 	'/#0 	
i()1#2 	3#4 	O5#6 	7#8 	9#: 	R;#< 	?=#> 	?#@ 	A#B 	LC#D 	QE# #FH 99-v,/0CAq1C0"]24 40s   :Dc                 t   t        | d   j                               D cg c]  \  }}|d   s||f }}}i |D ]'  \  }}|d   D ]  }j                  |d      dz   |<    ) t        fd      }|D cg c]  \  }}||d   v s||f }}}|j	                  d        |d   d   S c c}}w c c}}w )	u   실외샷 1개 선택 — 데이터 규칙: 지상 접근 loc(실외 & anchor 아닌 실외
    멤버 중 shot 최소 loc = 접근/입구 성격) 샷 우선, 없으면 wide 실외.r   r4   loc_idsr   rB   c                     |    S r   rC   )l
loc_countss    r   <lambda>z"pick_ground_shot.<locals>.<lambda>   s	    z!}r>   )keyc                 ^    | d   j                  d      xs i j                  d      dk(  rdS dS )NrB   stagingframing_scalewider   r(   )kvs    r   ra   z"pick_ground_shot.<locals>.<lambda>   s6    BqEIIi$8$>BO$$/a 6456r>   )r!   r"   r(   minsort)	r+   r   r   outdoorrZ   r_   
ground_loccandsr`   s	           @r   pick_ground_shotrn      s     #)w)=)=)?"@ &"@$!Qn 1v"@G & J19A&NN1a014JqM   Z%<=J 'F1:9+EaVEF	JJ 6J 78A;& Gs   B.:B4
B4c                    | d   |   }t         j                  dz  |z  }|j                  dd       t        dz  }dj	                  ddd	d
ddddddd	dt        |j                  d      xs i j                  d      xs d	      t        j                  |      g      }t        j                  | d||g|dz        }| d   D cg c]  }|d   |d   v s| }	}dj	                  d |	D              }
dj	                  dddddd	d d!d"d#d$d	d%|
d	t        j                  |      d	t        j                  g      }t        j                  | d&|||g|d'z         y c c}w )(Nr   	outdoor_dT)parentsexist_okrN   r@   z?The attached image is a TOP-DOWN site plan of one real propertyz1(circled letters are site markers, never people).rL   zEDraw the clean LINE-ART sketch of the EYE-LEVEL view described below:zEthin dark ink lines on plain white, no colour, no shading. The cameraz@stands ON the ground INSIDE the scene at human eye height (aboutuG   1.6 m) — NOT above it. Correct perspective at real-world human scale,zEhorizon at natural eye level. Show the structures, surfaces, openingsz7and approaches the plan places in front of that camera.uA   No people, no text, no letters, no circles — pure line drawing.z!CAMERA (from production staging):rd   camera_direction_camview_v2z
sketch.pngrO   r   r6   r]   c              3   h   K   | ]*  }d |j                  d       d|j                  d        , yw)z- labelrJ   summaryNrg   )r   r;   s     r   r   zshot_plate.<locals>.<genexpr>   s1     RTBquuW~.by1A0BCTs   02z=The FIRST attached image is a LINE-ART sketch of one camera'suF   eye-level view of a real outdoor place — composition and perspectivezBground truth. The SECOND attached image is the property's top-downuC   site plan — use it ONLY for spatial relations and fixtures; neverz'copy its top-down viewpoint or markers.zCRender the PHOTOREALISTIC EMPTY view exactly as the line-art frameszBit: same framing, perspective, structures, real-world human scale.uC   Completely unpopulated — no people, no figures. No text, letters,zCcircles, arrows or sketch lines. Pure photographic realism, naturalzweathered materials.z-WHAT THIS PLACE LOOKS LIKE (production data):_plate_v2rootz	plate.png)r	   OUTmkdirrU   r    strr(   Cstaging_linesrT   EYE_LEVEL_CONTRACT)r+   r.   skr   droot_pngsketch_promptsketchr;   locs	loc_linesplate_prompts               r   
shot_plater      s   grA	b AGGD4G(m#HIII;
OOJQOAK
+QUU9#(();<BC	 M  YY"[)=z !L 02FY'G'!1X;!I,+FA'DG		RTRRI99GPLM1
MLMM
7
AOOAA$8$8 L" IIM"L7I;(' Hs   EEc                  t   t        j                         } | j                  ddg d       | j                  dd        | j                         }t	        j
                         }|j                  dv rt        |      }nt	        j                  d      }|j                  d	v rt        ||       |j                  d
v rt        dz  }|j                         rdddt	        j                  |      g}t	        j                  dd|t        j                  d      }t	        j                   d|       t#        d|j%                  d      d|j%                  d             |j                  dv r2|j&                  xs t)        |      }t#        d|       t+        |||       t	        j,                  dd|j                  d       y )Nz--onlyall)r   r.   rootreadbackshot)defaultchoicesz--shot)r   )r   r.   r   )r   r   )r   r   rN   textzThis is a top-down site plan with circled capital letters and a legend panel. List every circled capital letter, list the legend entries as written, and say whether any interior room layout is exposed.)typer   forest_root_readbackz#You read technical plans precisely.r   r   root_readback_v2zreadback v2:letters_foundz	interior:interior_layout_exposed)r   r   zchosen outdoor shot:stage
s8_root_v2)kindr   done)argparseArgumentParseradd_argument
parse_argsr	   
load_recononlyr2   	load_planr   rU   existspng_data_urlr#   r%   READBACK_SCHEMAr'   r)   r(   r   rn   r   runlog)apargsr+   r.   pngr-   rbr   s           r   mainr      so   		 	 	"BOOHeG  IOOHdO+==?DLLNEyyO#U|{{>*yyO#tyy'']"::<#9:
 NN3')D -/TR//u>BKK*B/."&&"9rvv&?@ByyO#YY1*51$b)5$#HHgdiiHIr>   __main__)__doc__r   jsonsyspathlibr   pathinsertr{   __file__parent
forest_libr	   forest_chainr|   s1_rootr%   ry   rU   r$   r2   r=   r   rn   r   r   __name__rC   r>   r   <module>r      s      
  3tH~,,- .   uuyC,$24j$,(^JD zF r>   