ó
    ™?Ûj–
  ã            	       óÈ  • S r SSKrSSKrSSKrSSKrSSKr\R                  R                  S\R                  R                  S5      5        \R                  R                  S\R                  R                  S5      5        SSK
r
S\
l        SSKJrJr  0 SS_S	S
_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS_SS _S!S"_S#S$_SS%_S&S'_S(S0ErS) rS1S* jrS+ r\S,:X  a…  \R(                  S	S  Hq  r\" \R                  " \R                  R/                  \S-5      5      5       H8  r\R                  R3                  \SS. S/-   5      (       a  M+  \" \" \5      SS09  M:     Ms     gg)2a;  to_glb.py -- an .ldr frame as a .glb a browser can spin (Ivy, Oct 23 2026: "Can you make it so I can rotate and pan and
zoom the building legos?"). Parts are LDraw meshes (~/lego/ldraw.py, mm, z up), each in its LDraw colour.
    python3 to_glb.py runs/me1          # every frame_*.ldr in a run that has no .glb yeté    Nz~/projects/brick_reef/joinsz~/legoT)ÚreadÚmeshé   ÚC91A09é   Ú0055BFé   ÚF2CD37é   Ú237841é   ÚFE8A18é   ÚC870A0é   Ú81007BéG   ÚA0A5A9é   ÚBBE90BéI   Ú5A93DBéH   Ú6C6E68é   ÚE4CD9Ei@  Ú720E0Fi  Ú0A3463éF   Ú582A12Ú1B2A34é   ÚF4F4F4é   c                 óÐ  • [         R                  R                  [        R                  * S-  / SQ5      n[        R
                  " U  Vs/ s H  o"R                  S   PM     snS5      n[        R                  " U  Vs/ s H  o"R                  S   PM     snS5      nU[        R                  X4-   S-  S4   -  SS oQR                  5       ofSS2S4==   U-  ss'   U$ s  snf s  snf )z±our frame (mm, z up) -> the page's 3D frame (y up, build centred). Saved next to the .glb so the page can place ghost
pieces and turn a mouse hit back into a point in our frame.r   )r   r   r   r   r   Né   )
ÚtrimeshÚtransformationsÚrotation_matrixÚnpÚpiÚminÚboundsÚmaxÚr_Úcopy)ÚmeshesÚRÚmÚloÚhiÚcÚVs          Ú,/home/ivy/projects/brick_reef/reef/to_glb.pyÚview_matrixr9      s¿   € ô 	×Ñ×/Ñ/´·±°¸±
ºIÓF€AÜ	�Š¡fÓ-¢f —‘˜!”¡fÑ-¨qÓ	1€B¼¿ºÑU[Ó?\ÒU[ÐPQÇÁÈÄÑU[Ñ?\Ð^_Ó8`°2Ø	
ŒR�U‰U�B‘G˜q‘= !Ð#Ñ$Ñ	$ b qÐ)€A¯v©v«x¨1¸2¸A¸2¸q¸5»ÀQ¹»ÈqÈùò .ùÒ?\s   Á	CÁ=C#c           
      ó°  • SSK nU=(       d    U SS S-   n/ n[        [        U 5      5       Hè  u  nu  pVn[        U5      R	                  5       oˆR                  U5        S V	s/ s H(  n	[        [        R                  US5      X™S-    S5      PM*     sn	S	/-   n
[        R                  R                  U[        R                  " U
[        UR                  5      S
45      R!                  [        R"                  5      S9Ul
        UR%                  XH45        Mê     U(       d  g['        U VVs/ s H  u  p¸UPM	     snn5      n[        R(                  " 5       nU H-  u  pHUR                  U5        UR+                  USU 3SU 3S9  M/     UR-                  U5        UR/                  SUR1                  5       0[3        USS S-   S5      5        U$ s  sn	f s  snnf )zœone named node per LDraw line ('k<line index>'), so a click on the page knows WHICH brick it hit (Ivy, Oct 23 2026:
repaint on her turn by clicking a brick)r   Néüÿÿÿú.glb)r   r   r   r   r   r$   éÿ   r   ©Úface_colorsÚk)Ú	node_nameÚ	geom_nameÚviewz
.view.jsonÚw)ÚjsonÚ	enumerater   r   r0   Úapply_transformÚintÚRGBÚgetr'   ÚvisualÚColorVisualsr*   ÚtileÚlenÚfacesÚastypeÚuint8Úappendr9   ÚSceneÚadd_geometryÚexportÚdumpÚtolistÚopen)ÚldrÚoutrE   ÚpartsÚjÚcolourÚnameÚTr3   ÚiÚrgbaÚ_r7   Úscs                 r8   Ú
ldr_to_glbrd      s”  € ó Ø
×
"��S�b�˜FÑ"€C¨B EÜ )¬$¨s«)Ö 4ÑˆÑˆF˜!Ü�‹J�O‰OÓˆ×0Ñ0°Ô3ÙENÓOÂYÀ””C—G‘G˜F HÓ-¨a°A±Ð6¸Ö;ÁYÑOÐSVÐRWÑWˆÜ—>‘>×.Ñ.¨q¼b¿gºgÀdÌSÐQR×QXÑQXË\Ð[\ÐL]Ó>^×>eÑ>eÔfh×fnÑfnÓ>oÐ.ÐpˆŒØ�‰�a�VÖñ	 !5ö
 ˜Ü¡5Ô)¢5™4˜1“Q¡5Ò)Ó*€A´·²³¨BÛ‰ˆØ	×Ñ˜!Ô˜bŸo™o¨a¸Q¸q¸c¸7ÐPQÐRSÐQTÈg˜oÓVñ à‡I�Iˆc„N�D—I‘I˜v q§x¡x£zÐ2´D¸¸S¸b¸ÀLÑ9PÐRUÓ4VÔWÐ`cÐYcùò Pùó *s   Á"/GÄ*G
c           	      ó2  • [        U 5      R                  5       n[        R                  R	                  U[
        R                  " / SQ[        UR                  5      S45      R                  [
        R                  5      S9Ul        UR                  U5        U$ )zaone piece, in OUR frame, for the page's ghost (the page multiplies it by the frame's view matrix))éx   éÜ   éŒ   r=   r   r>   )r   r0   r'   rK   rL   r*   rM   rN   rO   rP   rQ   rU   )r^   rZ   r3   s      r8   Úpart_glbri       s’   € äˆT‹
�‰Ó€A¤g§n¡n×&AÑ&AÀ!ÔQS×QXÒQXÒYmÔpsÐtu×t{Ñt{Óp|Ð~ð  pAó  RB÷  RIñ  RIô  JL÷  JRñ  JRó  RSÐ&Að  'T˜1œ8Ø‡H�HˆS„M˜#�:ó    Ú__main__zframe_*.ldrr;   r<   )Úflush)N)Ú__doc__ÚsysÚosÚglobÚnumpyr*   r'   ÚpathÚinsertÚ
expanduserÚkitÚ	ALLOW_ANYÚfactsr   r   rI   r9   rd   ri   Ú__name__ÚargvÚrunÚsortedÚjoinÚlÚexistsÚprint© rj   r8   Ú<module>r�      sÂ  ðñ]÷ Ó ß Ø ‡�‡���2—7‘7×%Ñ%Ð&CÓDÔ EÀsÇxÁxÇÁÐWXÐZ\×ZaÑZa×ZlÑZlÐmuÓZvÔGwÛ 
˜DˆCŒMß ðF€qˆ(ð F�A�xð F  Xð F¨q°(ð F¸BÀð FÈ!ÈXð FÐWYÐ[cð FÐegÐiqð FÐsuÐwð FØ	ˆ8ðFØ˜ðFØ#% xðFØ14°hðFØ@CÀXðFØOQÐS[ðFØ]^Ð`hðFØjlÐnvðFØxzð  }EñF€òQôdòð ˆzÓØ�x‰x˜˜‹|ˆÙ˜Ÿ	š	 "§'¡'§,¡,¨s°MÓ"BÓCÖDˆAØ—7‘7—>‘> ! C R &¨6¡/×2Ó2±E¹*ÀQ»-ÈtÔ4Tó Eò ð rj   