
    HjO%              
          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ej                  dz  ZdZddddd	d
ddidg ddddiddd
dg ddddddddidddiddddgdddddd
dddiddg dddZd ZdedefdZd Zddddiddddidddiddidg dddZdefd Zd! Zed"k(  r e        yy)#u&  s1 — 뿌리(root): LLM 요소 선정(R1) → 통합 조감 스케치 생성(R2, A/B) → readback.

사용: .venv/bin/python s1_root.py [--only plan|image|readback]
산출: plans/root_plan.json, out/root/root_A.png(순수 T2I), root_B.png(배치도 I2I),
      plans/root_readback_{A,B}.json
    N)Pathroota  You are the master planner for a group of connected filming locations
(one real-world place made of indoor and outdoor parts). You are given the place's
member descriptions and the FULL content of every shot that happens there.

Your job: design ONE comprehensive TOP-DOWN aerial site sketch that lets every later
image of any of these shots stay spatially consistent. Select the elements that must
appear on that single sketch.

Hard rules:
- The sketch shows the place from directly above: structures (roof outline), outdoor
  areas, approach paths, and every OPENING (door, gate, window, stair/level access).
- NEVER expose interior floor plans or interior furniture. Indoor action may only be
  represented by its openings (the window/door through which it is visible or
  reached) and by elements visible from outside.
- Every shot must be covered: for each shot, the elements a viewer would need to
  locate that shot's action on the sketch (its opening, area, or approach).
- Keep it compact: at most 10 elements, each with a single capital letter ID
  (A, B, C, ...) and a SHORT English name (1-3 words) for the legend.
- Placement phrases must be relative and physical (e.g. "on the north edge of the
  roof", "at the bottom of the exterior stair"), grounded in the given data only.
- Do not invent features that contradict the member descriptions. Do not use any
  proper names in element names; use generic physical terms.objectarraystringzsingle capital letter)typedescriptionr   )	structureopeningfixtureapproachsurround)r   enumz"which shots/member text justify it)idname_encategory	placement	groundingF)r   
propertiesrequiredadditionalProperties)r   items)shot_keyelement_idsr   r   z3overall massing/orientation guidance for the sketch)elementscoveragesketch_noteslegend_orderc                    t        j                  | d         }dj                  d t        | d   j	                               D              }d|z   dz   |z   dz   }t        j
                  dt        |t        d	
      }t        |j                  dg             dkD  r+t        j                  dddd dt        |d          d       t        j                  d|       |j                  dg       D ch c]  }|d   	 }}t        t        | d         |z
        }t        dt        |d          dt        |       dt        | d          d|rd| ndz          |S c c}w )Nmembersz

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

ALL SHOTS AT THIS PLACE:

z7

Design the single aerial site sketch element set now.forest_root_plangptmodelr   
   warns1z	elements>: kindstagemsg	root_planr   r   zR1: z elements, coverage /z shotsz	 MISSING= )r"   members_blockjoinsortedr   llm	R1_SYSTEM	R1_SCHEMAlengetrunlog	save_plansetprint)reconr    shot_blocksuserplanccoveredmissings           r'   r1_planrL   Q   sv   ooeI./G++ G'-eGn.B.B.D'EG GK 	W$
,	-/:	;
E	F 	
 55#YiuMD
488J#$r)	&4bTCZ(8$9#:;= 	>KKT"&*hhz2&>?&>q}&>G?Sw(723G	DT*%&'';CL>c%.!"&*FMy	-BSUW XK	 @s   .Emembers_textreturnc                      dj                  d | d   D              }dj                  d | d   D              }dj                  dddd	d
dd|d
d| j                  dd
      d
dddddd
dd|d
dd|d
ddddg      S )N
c              3   D   K   | ]  }d |d    d|d    d|d      yw)(r   z) r   u    — r   N r$   es     r'   r(   z sketch_prompt.<locals>.<genexpr>h   s8      #!A AdG9Bq|nE!K.)9:!s    r   z, c              3   R   K   | ]  }|d     d|d   j                           ! yw)r   r1   r   N)upperrT   s     r'   r(   z sketch_prompt.<locals>.<genexpr>k   s3      H6F1T7)2a	l((*+,6Fs   %'zHONE hand-drawn TOP-DOWN aerial SITE SKETCH of a single real-world place,zEin clean technical sketch style: dark ink outlines, light flat colourzAwashes, straight-down view. NOT a photograph, NOT a 3D render, nozperspective, no photo textures.r8   uI   The place consists of these connected parts — draw them TOGETHER as onezCcoherent site (one main structure plus its immediate surroundings):z%Overall massing/orientation guidance:r   zFDraw ONLY what is visible from above and from outside: the structure'szFroof outline and what stands on top of it, open ground areas, approachzHpaths and stairs, and each opening (door, gate, window, level access) aszHpart of the boundary it belongs to. Do NOT draw any interior room layoutu?   or interior furniture — buildings show their roof plane only.zGMark each of the following elements at its position with a small circlez%containing its single capital letter:zEOn the RIGHT side of the image, add a clean legend panel listing eachzCcircled letter with its English name in small neat capital letters:zGThe circled letters and the legend panel are the ONLY text and the ONLYzFcircular marks allowed. No other labels, numbers, logos or watermarks.zHInclude a modest margin of the immediate surroundings so the place readszGin context; keep geometry simple, unambiguous and physically plausible.)r:   r@   )rH   rM   el_lineslegend_liness       r'   sketch_promptrZ   g   s    yy #j!# #H 99 H6::6FH HL99ROK)
SM
/$
PPRRI
Q/
OM
QPRQ=      c                 4   t        j                  | d         }t        ||      }t        j                  d|d t        dz         | j                  d      r*|dz   }t        j                  d|| d   gt        dz         y t        j                  d	d
dd       y )Nr    
root_A_t2iz
root_A.png)refsout_pathbaseline_aerialuK  

The attached image is the existing clean top-down site plan of this place. KEEP its geometry, proportions and layout EXACTLY — same structures, same openings, same surroundings. Restyle it into the hand-drawn sketch style described above and ADD the circled capital letters and the right-side legend panel. Change nothing else.root_B_from_planz
root_B.pngr/   r0   zno baseline aerial for R-Br2   )r"   r9   rZ   img_gptOUTDIRr@   rA   )rE   rH   rM   promptedit_prompts        r'   	r2_imagesrf      s    ??5#34L4.FIIlF8MNyy"#M
 	
		$k?P9Q8R!L0	2 	
&48TUVr[   boolean)letters_foundlegend_entriesinterior_layout_exposednotesvariantc                    t         d| dz  }|j                         sy dddt        j                  |      g}t        j                  dd|t
        d	      }t        j                  d
| |       | d   D ch c]  }|d   	 }}t        |j                  d      xs g       }t        d| dt        |       dt        |       d|j                  d       d|j                  dd      d d  
       y c c}w )Nroot_z.pngtextzThis is a top-down site sketch with circled capital letters and a legend panel. List every circled capital letter you can find, list the legend entries as written, and say whether any interior room layout is exposed.)r   ro   forest_root_readbackz&You read technical sketches precisely.r+   r,   root_readback_r   r   rh   z	readback z
: letters z	 vs plan z | interior_exposed=rj   z | rk   r8   x   )rc   existsr"   png_data_urlr<   READBACK_SCHEMArB   rC   r@   rD   r;   )rH   rl   pngrG   rbrU   wantgots           r'   readbackrz      s   
U7)4(
(C::<"	#
 	
sD 
%(P_E
3BKK.	*B/!*-.-AdG-D.
bff_%+
,C	IgYjYvd|n M ff%>?@BFF7SUDVW[X[D\C]_ ` /s   7C2c                     t        j                         } | j                  ddg d       | j                         }t	        j
                         }|j                  dv rt        |      }nt	        j                  d      }|j                  dv rt        ||       |j                  dv rd	D ]  }t        ||        t	        j                  d
d|j                  d       y )Nz--onlyall)r|   rH   imagerz   )defaultchoices)r|   rH   r6   )r|   r}   )r|   rz   )ABr4   s1_root)r3   r4   done)argparseArgumentParseradd_argument
parse_argsr"   
load_recononlyrL   	load_planrf   rz   rA   )apargsrE   rH   vs        r'   mainr      s    		 	 	"BOOHe@  B==?DLLNEyyO#u~{{;'yy$$%yy''AT1 HHg	499EFr[   __main__)__doc__r   jsonsyspathlibr   pathinsertstr__file__parent
forest_libr"   OUTrc   r=   r>   rL   rZ   rf   ru   rz   r   __name__rS   r[   r'   <module>r      s     
  3tH~,,- . 	
@	0   #+<ST &1)1 <S !T"((!3*21U"W T(-
$  !' 2,3vx>P#Q (7(-
 "*(]_!(FH3EFA!D I!K&	R,%c %c %PW* ")VX4FG#*fh5GH$*I#6(#	!`C `*G$ zF r[   