Ë
    É`ºjc  ã                  ó  — d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ ddlZdZdd„Zdd„Zdd	„Zdd
„Zdd„Zdd„Zdd„Zd d„Zd!d„Zd"d„Zd#d$d„Zd%d„Zd&d„Zd'd„Zd(d„Zedfd)d„Zd*d„Z e!dk(  r e «        yy)+a{  Prepare topology-faithful, multi-resolution graphs from a triangle CAD mesh.

The requested resolutions are *vertex/node budgets*.  Open3D's quadric error
decimator takes triangle budgets, so this program deliberately records both the
requested node budget and the triangle budget passed to the decimator.  The
resulting number of graph nodes is always measured, never inferred.
é    )ÚannotationsN)ÚPath)ÚAny)ià.  ip  iˆ  i¸  iÜ  iî  i,  éd   c                 óV   — t        t        «      j                  «       j                  d   S )Né   )r   Ú__file__ÚresolveÚparents© ó    õ   ì „ì²˜ë¦¬/cad_graphs.pyÚ_rootr      s    € Ü”‹>×!Ñ!Ó#×+Ñ+¨AÑ.Ð.r   c                 ó¶   — t        j                  t         j                  «      j                  } t	        | t        j                  «       dk(  rdz  «      S dz  «      S )NÚDarwini   i   )ÚresourceÚ	getrusageÚRUSAGE_SELFÚ	ru_maxrssÚfloatÚplatformÚsystem)Úrsss    r   Ú_peak_memory_mbr      sG   € ä
×
Ñ
œX×1Ñ1Ó
2×
<Ñ
<€CÜ�¤x§¡Ó'8¸HÒ'D˜ÑOÓPÐPÈ$ÑOÓPÐPr   c                ón   — t        j                  | ddd¬«      j                  t         j                  «      S )Nç        ©ÚnanÚposinfÚneginf)ÚnpÚ
nan_to_numÚastypeÚfloat32)Úas    r   Ú_finiter&   $   s&   € Ü�=‰=˜ ¨C¸Ô<×CÑCÄBÇJÁJÓOÐOr   c                óz   — t        j                  t        j                  | | z  j                  d¬«      d«      «      S )Néÿÿÿÿ©Úaxisr   )r!   ÚsqrtÚmaximumÚsum)Úvs    r   Ú
_safe_normr/   (   s+   € Ü�7‰7”2—:‘:˜q 1™uŸk™k¨r˜kÓ2°CÓ8Ó9Ð9r   c                óv  — dd l }|j                  j                  t        | «      d¬«      }t	        |j
                  «      dk(  st	        |j                  «      dk(  rt        d| › �«      ‚|j                  «        |j                  «        |j                  «        |j                  «        |j                  «        |S )Nr   F)Úenable_post_processingzNo triangles were read from )Úopen3dÚioÚread_triangle_meshÚstrÚlenÚverticesÚ	trianglesÚ
ValueErrorÚremove_duplicated_verticesÚremove_duplicated_trianglesÚremove_degenerate_trianglesÚremove_unreferenced_verticesÚcompute_vertex_normals)ÚpathÚo3dÚmeshs      r   Ú
_load_meshrB   ,   s™   € Ûà�6‰6×$Ñ$¤S¨£YÀuÐ$ÓM€DÜ
ˆ4�=‰=Ó˜QÒ¤# d§n¡nÓ"5¸Ò":ÜÐ7¸°vÐ>Ó?Ð?ð 	×#Ñ#Ô%Ø×$Ñ$Ô&Ø×$Ñ$Ô&Ø×%Ñ%Ô'Ø×ÑÔ!Ø€Kr   c                óü  — t        j                  | j                  t         j                  ¬«      j	                  «       }t        j                  | j
                  t         j                  ¬«      j	                  «       }t        j                  | j                  t         j                  ¬«      j	                  «       }t        |«      d d …d f   }t        j                  ||t        j                  |«      |dkD  ¬«      }|||fS )N©Údtypeçê-�™—q=©ÚoutÚwhere)r!   Úasarrayr7   Úfloat64Úcopyr8   Úint64Úvertex_normalsr/   ÚdivideÚ
zeros_like)rA   r.   ÚfÚnÚnlens        r   Ú_mesh_arraysrT   =   s¥   € Ü
�
‰
�4—=‘=¬¯
©
Ô3×8Ñ8Ó:€AÜ
�
‰
�4—>‘>¬¯©Ô2×7Ñ7Ó9€AÜ
�
‰
�4×&Ñ&¬b¯j©jÔ9×>Ñ>Ó@€AÜ�a‹=š˜D˜Ñ!€DÜ
�	‰	�!�TœrŸ}™}¨QÓ/°t¸e±|ÔD€AØˆa�ˆ7€Nr   c                óX	  — t        | «      }|}t        j                  |dd…ddgf   |dd…ddgf   |dd…ddgf   fd¬«      }t        j                  |d¬«      }t        j                  |ddd¬«      \  }}}	|	dk(  }
t        j
                  | |dd…df      | |dd…df      z
  | |dd…df      | |dd…df      z
  «      }t        |«      dd…df   }t        j                  ||t        j                  |«      |dkD  ¬	«      }t        j                  |||fd¬«      }t        j                  t        |«      d
ft        j                  ¬«      }t        j                  j                  |||«       t        j                  t        |«      dt        j                  ¬«      }t        j                  t        |«      dt        j                  ¬«      }t        |«      D ]!  \  }}||   dk  r|||<   Œ||   dk  sŒ|||<   Œ# t        j                  t        |«      t        j                  ¬«      }|dk\  }t        j                   t        j"                  |||      |||      z  j%                  d«      dd«      «      ||<   |
|	dk7  z  |t        j&                  d«      kD  z  }t        j                  |dd…df   |dd…df   f«      }t        j                  |dd…df   |dd…df   f«      }| |   | |   z
  }t        |«      }t        j                  ||dd…df   t        j                  |«      |dd…df   dkD  ¬	«      }t        j(                  ||||   ||   z  j%                  d«      t        j*                  |d«      t        j*                  |
d«      t        j*                  |d«      f«      }t        j,                  ||¬«      j/                  t        j0                  «      }t        j2                  ||f«      j/                  t        j0                  «      t5        |«      t        j,                  ||
   j7                  «       |¬«      j/                  t8        «      t        j,                  ||   j7                  «       |¬«      j/                  t8        «      ||j/                  t        j0                  «      |	dœS )z>Build edges solely from triangle topology (never spatial KNN).Nr   r   é   r)   T)r*   Úreturn_inverseÚreturn_countsrF   rG   é   rD   r(   g      >@)Ú	minlength)Ú
edge_indexÚ	edge_attrÚboundary_nodeÚfeature_nodeÚdegreeÚunique_edgesÚedge_counts)r6   r!   ÚconcatenateÚsortÚuniqueÚcrossr/   rO   rP   ÚzerosrK   ÚaddÚatÚfullrM   Ú	enumerateÚarccosÚclipr-   Údeg2radÚcolumn_stackÚtileÚbincountr#   Úint32Úvstackr&   ÚravelÚbool)r7   ÚfacesÚnormalsrR   ÚtriÚdirectedÚ
undirectedÚkeysÚinverseÚcountsÚ
boundary_uÚface_normalÚflenÚedge_face_normalÚsum_nÚfirstÚsecondÚhalf_iÚedge_iÚdihedralÚbothÚ	feature_uÚsrcÚdstÚdeltaÚlengthÚ	directionÚattrsr_   s                                r   Ú	_topologyr�   F   s  € äˆH‹€AØ
€CÜ�~‰~˜s¢1 q¨! f 9™~¨s²1°q¸!°f°9©~¸sÂ1ÀqÈ!ÀfÀ9¹~ÐNÐUVÔW€HÜ—‘˜¨Ô*€JÜŸI™I j°qÈÐ]aÔbÑ€Dˆ'�6Ø˜1‘€Jä—(‘(˜8 Cª¨1¨¡IÑ.°¸#ºaÀ¸d¹)Ñ1DÑDÀhÈsÒSTÐVWÐSWÉyÑFYÐ\dÐehÒijÐlmÐimÑenÑ\oÑFoÓp€KÜ�kÓ"¢1 d 7Ñ+€DÜ—)‘)˜K¨´2·=±=ÀÓ3MÐUYÐ\aÑUaÔb€Kä—~‘~ {°KÀÐ&MÐTUÔVÐÜ�H‰H”c˜$“i �^¬2¯:©:Ô6€EÜ‡F�F‡I�Iˆe�WÐ.Ô/ä�G‰G”C˜“I˜r¬¯©Ô2€EÜ�W‰W”S˜“Y ¬"¯(©(Ô3€FÜ# GÖ,‰ˆ�Ø�‰=˜1ÒØ"ˆE�&ŠMØ�F‰^˜aÓØ#ˆF�6ŠNð	 -ô
 �x‰xœ˜D›	¬¯©Ô4€HØ�Q‰;€DÜ—Y‘YœrŸw™wÐ(8¸¸t¹Ñ(EÐHXÐY_Ð`dÑYeÑHfÑ(f×'kÑ'kÐlmÓ'nÐprÐtuÓvÓw€HˆT�Nà˜f¨™kÑ*¨h¼¿¹ÀDÓ9IÑ.IÑJ€IÜ
�.‰.˜$šq !˜t™* dª1¨a¨4¡jÐ1Ó
2€CÜ
�.‰.˜$šq !˜t™* dª1¨a¨4¡jÐ1Ó
2€CØ�S‰M˜H S™MÑ)€EÜ˜Ó€FÜ—	‘	˜% ª¨4¨¡´b·m±mÀEÓ6JÐRXÒYZÐ\`ÐY`ÑRaÐdiÑRiÔj€IÜ�O‰O˜V Y°¸±ÀÈÁÑ1L×0QÑ0QÐRSÓ0TÜŸW™W X¨qÓ1´2·7±7¸:ÀqÓ3IÌ2Ï7É7ÐS\Ð^_ÓK`ðbó c€Eä�[‰[˜¨Ô*×1Ñ1´"·(±(Ó;€Fä—i‘i  c 
Ó+×2Ñ2´2·8±8Ó<Ì7ÐSXË>ÜŸ™ T¨*Ñ%5×%;Ñ%;Ó%=ÈÔK×RÑRÔSWÓXÜŸ™ D¨¡O×$9Ñ$9Ó$;ÀqÔI×PÑPÔQUÓVØ¨$¯+©+´b·h±hÓ*?ÐPVñ	ð r   c                ó
  — t        | «      }| |dd…df      | |dd…df      z
  | |dd…df      | |dd…df      z
  | |dd…df      | |dd…df      z
  }}}t        t        j                  || «      «      }|dz  }t        j                  |t        j
                  ¬«      }	t        j                  j                  |	|j                  «       t        j                  |dz  d«      «       g }
d	D ]7  \  }}| |dd…|f      | |dd…df      z
  | |dd…|f      | |dd…df      z
  }}Œ9 t        d«      D ]Ó  }|dd…|dz   dz  f   |dd…|dz   dz  f   }}| |   | |dd…|f      z
  | |   | |dd…|f      z
  }}t        |«      t        |«      z  }|
j                  t        j                  t        j                  t        j                  ||z  j                  d«      |t        j                   |«      |d
kD  ¬«      dd«      «      «       ŒÕ t        j                  |t        j
                  ¬«      }t#        |
«      D ]-  \  }}t        j                  j                  ||dd…|f   |«       Œ/ t        j$                  |d   t        j&                  dt        j&                  z  «      }t        j                  ||z
  |	t        j                  |«      |	dkD  ¬«      }t        j                  |dft        j
                  ¬«      }t#        |
«      D ]í  \  }}t        j                  dt        j(                  |«      t        j*                  |«      t        j,                  t        j(                  |«      «      dkD  ¬«      }|dd…|dz   dz  f   |dd…|dz   dz  f   }}| |   | |   z
  }t        j                  j                  |||dd…df   |z  «       t        j                  j                  |||dd…df    |z  «       Œï t        j                  t        |«      d|	z  t        j                  |«      |	dkD  ¬«      }|	dkD  |d   dk\  z  t        j.                  |«      z  t        j.                  |«      z  }t        j0                  |	|t        j2                  |d   d«      z  |t        j,                  |«      |d   |d   |d   f«      }t        j.                  |«      }|dd…dd…fxx   |dd…df   z  cc<   t5        |«      |j7                  t8        «      g d¢fS )zSFinite, intrinsic-ish local features; curvature is unsigned due to STL orientation.Nr   r   rV   ç      à?rD   ç      @rY   ))r   rV   )rV   r   )r   r   gVçž¯Ò<rG   r(   r]   rF   g      ð?g      @g»½×Ùß|Û=r_   r^   é   )Úvertex_area_mm2Úmean_incident_angle_radÚmean_curvature_abs_1_per_mmÚ gaussian_curvature_abs_1_per_mm2r]   r^   Útopological_degree)r6   r/   r!   re   rf   rK   rg   rh   rs   ÚrepeatÚrangeÚappendrk   rl   rO   r-   Ú	ones_likerj   rI   ÚpiÚtanrP   ÚabsÚisfinitern   r,   r&   r#   rt   )r.   rQ   ÚtoporR   Úe01Úe12Úe20Údbl_areaÚareaÚvertex_areaÚanglesr%   ÚbÚxÚyÚcornerÚdenomÚ	angle_sumÚangÚtargetÚgaussianÚlapÚcotÚiÚjÚdÚmean_magÚcurvature_validÚvalids                                r   Ú_geometry_featuresrº   s   sƒ  € äˆA‹€AØ�aš˜1˜‘g‘J  1¢Q¨ T¡7¡Ñ+¨Q¨q²°A°©w©Z¸!¸AºaÀ¸d¹G¹*Ñ-DÀaÈÊ!ÈQÈ$ÉÁjÐSTÐUVÒWXÐZ[ÐW[ÑU\ÑS]ÑF]ˆcˆ€CÜœ"Ÿ(™( 3¨¨Ó-Ó.€HØ�c‰>€DÜ—(‘(˜1¤B§J¡JÔ/€KÜ‡F�F‡I�Iˆk˜1Ÿ7™7›9¤b§i¡i°°s±
¸AÓ&>Ô?à€FÛ(‰ˆˆ1Ø�’1�a�4‘‰z˜A˜a¢ 1 ™g™JÑ&¨¨!ªA¨q¨D©'©
°Q°qº¸A¸±w±ZÑ(?ˆ1‰ð )ô ˜–(ˆØ’�V˜a‘Z 1Ñ$Ð$Ñ% qª¨V°a©Z¸1Ñ,<Ð)<Ñ'=ˆ1ˆØ�‰t�a˜š!˜V˜)™‘oÑ% q¨¡t¨a°²!°V°)±©oÑ'=ˆ1ˆÜ˜1“¤
¨1£Ñ-ˆØ�‰”b—i‘i¤§¡¬¯	©	°1°q±5·+±+¸a³.À%ÌRÏ\É\ÐZ_ÓM`ÐhmÐpuÑhuÔ(vÐxzÐ|}Ó ~Óõ  	Að	 ô
 —‘˜¤"§*¡*Ô-€IÜ  Ö(‰ˆ�¬"¯&©&¯)©)°I¸qÂÀFÀ¹|ÈSÕ*QÐ(Ü�X‰X�d˜?Ñ+¬R¯U©U°A¼¿¹±IÓ>€FÜ�y‰y˜ )Ñ+¨[¼b¿h¹hÀq»kÐQ\Ð_dÑQdÔe€Hä
�(‰(�A�q�6¤§¡Ô
,€CÜ  Ö(‰ˆ�Ü�i‰i˜œRŸV™V C›[¬b¯m©m¸CÓ.@ÌÏÉÌrÏvÉvÐVYË{ÓH[Ð^cÑHcÔdˆØ’�V˜a‘Z 1Ñ$Ð$Ñ% qª¨V°a©Z¸1Ñ,<Ð)<Ñ'=ˆ1ˆØˆa‰D�1�Q‘4‰KˆÜ
�‰�	‰	�#�q˜#ša ˜g™,¨Ñ*Ô+Ü
�‰�	‰	�#�q˜3šq $˜w™<˜-¨!Ñ+Õ,ð )ô �y‰yœ C›¨#°Ñ*;ÄÇÁÈ!ÃÐT_ÐbgÑTgÔh€HØ" UÑ*¨t°H©~ÀÑ/BÑCÄbÇkÁkÐRZÓF[Ñ[Ô^`×^iÑ^iÐjrÓ^sÑs€OÜ
�‰˜ i´"·*±*¸TÀ(¹^ÈQÓ2OÑ&OÐQYÜŸ™ Ó)¨4°Ñ+@À$À~ÑBVÐX\Ð]eÑXfðhó 	i€Aä�K‰K˜‹N€EØ	Š!ˆQˆqˆSˆ&ƒM�_¢Q¨ WÑ-Ñ-ƒMÜ�1‹:�u—|‘|¤DÓ)ò  ,Tð  Tð  Tr   c                ó   ‡— t        j                  | «      Šˆfd„}|D ]2  \  }} |t        |«      «       |t        |«      «      }}||k7  sŒ.|‰|<   Œ4 t        t	        | «      D �ch c]
  } ||«      ’Œ c}«      S c c}w )Nc                óJ   •— ‰|    | k7  r‰‰|       ‰| <   ‰|    } ‰|    | k7  rŒ| S )Nr   )r%   Úparents    €r   Úfindz_components.<locals>.findœ   s:   ø€ Ø�Q‰i˜1ŠnØ˜v a™yÑ)ˆF�1‰I¨v°a©y¨1ð �Q‰i˜1‹nàˆr   )r!   ÚarangeÚintr6   rš   )rR   r`   r¾   r%   r©   r´   r½   s         @r   Ú_componentsrÁ   š   st   ø€ Ü�Y‰Y�q‹\€Fôó ‰ˆˆ1Ù”C˜“F‹|™T¤# a£&›\ˆ1ˆØ�‹6˜q�6˜!’9ð ô ¤ q¤Ó*¡˜A‘�Q• Ñ*Ó+Ð+ùÒ*s   Á%A;c           
     ó�  — t        j                  | j                  «      t        j                  | j                  «      }}t	        t        j
                  ||dd…df      ||dd…df      z
  ||dd…df      ||dd…df      z
  «      «      dz  }|j                  t        |«      |d||j                  «       z  ¬«      }|j                  |«      |j                  |«      }}||z   dkD  }	d||	   z
  ||	<   d||	   z
  ||	<   |||df      |dd…df   |||df      |||df      z
  z  z   |dd…df   |||df      |||df      z
  z  z   S )zODeterministic area-uniform triangle samples, rather than vertex-biased samples.Nr   r   rV   r‘   T)ÚsizeÚreplaceÚp)
r!   rJ   r7   r8   r/   re   Úchoicer6   r-   Úrandom)
rA   ÚcountÚrngr.   rQ   r%   ÚidsÚr1Úr2Úflips
             r   Ú_area_uniform_pointsrÎ   ¦   sd  € ä�:‰:�d—m‘mÓ$¤b§j¡j°·±Ó&@€q€AÜ”2—8‘8˜A˜a¢ 1 ™g™J¨¨1ªQ°¨T©7©Ñ3°Q°qº¸A¸±w±ZÀ!ÀAÂaÈÀdÁGÁ*Ñ5LÓMÓNÐQSÑS€AØ
�*‰*”S˜“V %°¸¸Q¿U¹U»W¹ˆ*Ó
E€CØ�Z‰Z˜Ó §
¡
¨5Ó 1ˆ€BØ�‰7�Q‰;€D 1 R¨¡X¡:˜˜4™¸!¸B¸t¹H¹*¨r°$©xØˆQˆs�Aˆv‰Y‰<˜"šQ ˜W™+¨¨1¨S°!¨V©9©¸¸!¸CÀ¸F¹)¹Ñ)DÑEÑEÈÊ1ÈdÈ7ÉÐWXÐYZÐ[^Ð`aÐ[aÑYbÑWcÐfgÐhiÐjmÐopÐjpÑhqÑfrÑWrÑHsÑsÐsr   c           
     ó  — ddl }t        j                  j                  d«      }t	        | ||«      }t	        |||«      }	 |j
                  j                  j                  «       }|j                  |j
                  j                  j                  j                  |«      «       |j
                  j                  j                  «       }|j                  |j
                  j                  j                  j                  | «      «       t        ||j                  |j                  j                  |j                  t        j                   «      «      «      d   j#                  «       z
  «      }	t        ||j                  |j                  j                  |j                  t        j                   «      «      «      d   j#                  «       z
  «      }
d}d
„ } ||	«       ||
«      dœ|fS # t$        $ rš}ddlm}  |t        j*                  |j,                  «      «      j/                  |d¬«      \  }	} |t        j*                  | j,                  «      «      j/                  |d¬«      \  }
}d	t1        |«      j2                  › �}Y d}~Œ´d}~ww xY w)zLBidirectional, area-uniform surface sampling queried against mesh triangles.r   Ni2(5ÚpointszUOpen3D RaycastingScene closest point on triangles; deterministic area-uniform samples©ÚcKDTreer(   ©Úworkersz2fallback nearest vertices (NOT surface distance): c                óÊ   — t        | j                  «       «      t        t        j                  | d«      «      t        | j	                  «       «      t        t        | «      «      dœS )Né_   )Úmean_mmÚp95_mmÚmax_mmÚsamples)r   Úmeanr!   Ú
percentileÚmaxrÀ   r6   )r¶   s    r   Ústatsz'_sample_surface_distance.<locals>.statsÁ   sc   € ¤U¨1¯6©6«8£_ÄÄbÇmÁmÐTUÐWYÓFZÓ@[ÔglÐmn×mrÑmrÓmtÓguô  CFô  GJð  KLó  GMó  CNñ  Oð  Or   )Úsource_to_simplifiedÚsimplified_to_source)r2   r!   rÇ   Údefault_rngrÎ   ÚtÚgeometryÚRaycastingSceneÚadd_trianglesÚTriangleMeshÚfrom_legacyr/   Úcompute_closest_pointsÚcoreÚTensorr#   r$   ÚnumpyÚ	ExceptionÚscipy.spatialrÒ   rJ   r7   ÚqueryÚtypeÚ__name__)Úsource_meshÚsimplified_meshÚsample_countr@   rÉ   Ú
src_pointsÚsimp_pointsÚtarget_sÚtarget_oÚ	d_forwardÚ	d_reverseÚmethodÚexcrÒ   Ú_rÞ   s                   r   Ú_sample_surface_distancerý   °   s6  € ãÜ
�)‰)×
Ñ
 Ó
)€CÜ% k°<ÀÓE€JÜ& ¸ÀcÓJ€Kð
[Ø—5‘5—>‘>×1Ñ1Ó3ˆ°X×5KÑ5KÈCÏEÉEÏNÉN×LgÑLg×LsÑLsð  uDó  MEô  6FØ—5‘5—>‘>×1Ñ1Ó3ˆ°X×5KÑ5KÈCÏEÉEÏNÉN×LgÑLg×LsÑLsÐtó  MAô  6BÜ˜z¨H×,KÑ,KÈCÏHÉHÏOÉOÐ\f×\mÑ\mÔnp×nxÑnxÓ\yÓLzÓ,{ð  }Eñ  -F÷  -Lñ  -Ló  -Nñ   Nó  Oˆ	Ü˜{¨X×-LÑ-LÈSÏXÉXÏ_É_Ð]h×]oÑ]oÔpr×pzÑpzÓ]{ÓM|Ó-}ð  Gñ  .H÷  .Nñ  .Nó  .Pñ   Pó  Qˆ	Øhˆò OÙ$)¨)Ó$4ÉeÐT]ÓN^Ñ_ÐagÐgÐgøô ò [Ý)ÙœrŸz™z¨/×*BÑ*BÓCÓD×JÑJÈ:Ð_aÐJÓb‰ˆ	�1ÙœrŸz™z¨+×*>Ñ*>Ó?Ó@×FÑFÀ{Ð\^ÐFÓ_‰ˆ	�1ØEÄdÈ3Ãi×FXÑFXÐEYÐZ�ûð	[ús   ¿FG# Ç#	JÇ,BJÊJc                óÂ   — ddl m}  || «      j                  |d¬«      \  }}|j                  t        j
                  «      |j                  t        j                  «      fS )Nr   rÑ   r(   rÓ   )rí   rÒ   rî   r#   r!   rq   r$   )Úsource_verticesr7   rÒ   r¶   Úixs        r   Ú_source_correspondencer  Å   sH   € Ý%Ù�OÓ$×*Ñ*¨8¸RÐ*Ó@�E€A€rØ�9‰9”R—X‘XÓ §¡¬¯©Ó 4Ð4Ð4r   c           
     óD  — t        j                  t        |«      dft         j                  «      }t        j                  t        |«      dft        «      }t        j
                  t        |«      t         j                  t         j                  «      }| €|||dfS ddlm} t        j                  | d¬«      }h d£}|j                  |j                  «      s(|||dt        |t        |j                  «      z
  «      › �fS  ||d	   «      j                  |d
¬«      \  }	}
|d   |
   |d   |
   }}d|j                  v r|d   |
   n#t        j                  |t         j                  «      }t        j                   ||z  j#                  d«      «      }|	dk  |dkD  z  }t        j$                  t        j                   |«      t        j                   |«      ||z  f«      }t        j&                  |ddd¬«      |dd |dd…df   t        j(                  |«      z  |dd |	|dd |||dfS )a  Map supplied analytic samples only when explicitly provided for this mesh.

    Mapping is nearest sample correspondence, with a conservative distance mask;
    it never silently substitutes samples from the reference CAD for an alternate
    ``--mesh``.  Signed principal values are retained as supplied, while the
    discrete unsigned channels remain available independently.
    rY   Nr   rÑ   F)Úallow_pickle>   Ú	k1_per_mmÚ	k2_per_mmÚ	points_mmzignored: missing r  r(   rÓ   r  r  Úparameter_normalsr   r’   gš™™™™™é?r   r   z¥nearest supplied analytic samples; valid iff distance < 3 mm and abs(normal dot parameter_normal) > 0.8; principal values stored as magnitudes, Gaussian retains sign)r!   rf   r6   r$   rt   ri   r   rí   rÒ   ÚloadÚissubsetÚfilesÚsortedÚsetrî   Ú	full_likerŸ   r-   rn   r"   r    )r?   r7   rv   Úvaluesr¹   ÚdistancerÒ   r%   Úrequiredr¶   r   Úk1Úk2Úsampled_normalÚ	alignmentÚcloseÚraws                    r   Ú_external_curvaturer  Ë   sé  € ô �X‰X”s˜8“} aÐ(¬"¯*©*Ó5€F¼r¿x¹xÌÈXËÐXYÐHZÔ\`Ó?a°uÜ�w‰w”s˜8“}¤b§f¡f¬b¯j©jÓ9€HØ€|˜F E¨8°TÐ9Ð9Ý%Ü
�‰� 5Ô)€AÚ6€HØ×Ñ˜QŸW™WÔ%Ø�u˜hÐ*;¼FÀ8ÌCÐPQ×PWÑPWËLÑCXÓ<YÐ;ZÐ([Ð[Ð[Ù�A�k‘NÓ#×)Ñ)¨(¸BÐ)Ó?�E€A€rØˆ{‰^˜BÑ  ;¡°Ñ!3ˆ€BØ3FÈ!Ï'É'Ñ3Q�QÐ*Ñ+¨BÒ/ÔWY×WcÑWcÐdlÔnp×ntÑntÓWu€NÜ—‘˜ .Ñ0×5Ñ5°aÓ8Ó9€Ið �‰W˜ R™Ñ(€Eô �/‰/œ2Ÿ6™6 "›:¤r§v¡v¨b£z°2°b±5Ð9Ó
:€CÜ—‘˜c r°"¸RÔ@€F‰1€IØ’Q˜�W‰~¤§¡¨CÓ 0Ñ0€E‰!€HØ€H‰Q€KØ�5˜(ð  %Lð  Lð  Lr   c                óB  — dd l }|j                  d«       dd lm} t	        | «      dz   dz  }|j                  dd|z  f¬«      }|j                  |dd«      }|j                  | D �cg c]  }|d   ‘Œ	 c}| D �cg c]  }|d	   d
   d   ‘Œ c}dd¬«       |j                  | D �cg c]  }|d   ‘Œ	 c}| D �cg c]  }|d	   d   d   ‘Œ c}dd¬«       |j                  d«       |j                  d«       |j                  d«       |j                  dd¬«       |j                  d¬«       t        | d«      D �]  \  }}|j                  |d|d¬«      }|d   |d   |d   }}
}	t	        |«      d k  r|n+|t        j                  dt	        |«      dz
  d t         ¬!«         }|j#                  |	d d …df   |	d d …df   |	d d …df   |d"d#d$d%d&d#¬'«
       |j%                  d(|d)   › d*|d   › �d+¬«       |j'                  d,d-¬.«       |j)                  d/«       |j+                  d0d1«       |j-                  d0d1«       |j/                  d0d1«       |j1                  «        �Œ" |j3                  «        |j5                  |d2¬3«       |j7                  |«       y c c}w c c}w c c}w c c}w )4Nr   ÚAggr“   é   g      @)Úfigsizer   Úactual_nodesr  rß   rØ   zo-u   source â†’ simplified)Úlabelrà   zs--u   simplified â†’ sourceÚlogzactual graph nodeszsurface p95 (mm)Tg333333Ó?)Úalphaé   )ÚfontsizerV   Ú3d)Ú
projectionÚpos_normÚ	curvatureru   i@  rD   ÚmagmaFg{®Gáz´?z#3b3b3bg¸…ëQ¸î?)r8   ÚcmapÚshadeÚ	linewidthÚ	edgecolorr  Úantialiasedzrequest Úrequested_nodesz nodes
actual é   é   iÉÿÿÿ)ÚelevÚazim)r   r   r   g¤p=
×£à¿g¤p=
×£à?é    )Údpi)Ú
matplotlibÚuseÚmatplotlib.pyplotÚpyplotr6   ÚfigureÚadd_subplotÚplotÚ
set_xscaleÚ
set_xlabelÚ
set_ylabelÚgridÚlegendrj   r!   ÚlinspacerÀ   Úplot_trisurfÚ	set_titleÚ	view_initÚset_box_aspectÚset_xlimÚset_ylimÚset_zlimÚset_axis_offÚtight_layoutÚsavefigr  )ÚgraphsrH   r3  ÚpltÚrowsÚfigÚaxÚgr´   rÅ   ÚcrQ   r4  s                r   Ú_save_figurerQ  ë   sá  € ÛØ‡N�N�5ÔÝ#Ü�‹K˜!‰O Ñ!€DØ
�*‰*˜b #¨¡*Ð-ˆ*Ó
.€CØ	�‰˜˜q !Ó	$€BØ‡G�G©Ó/© 1ˆQˆ~Ó¨Ñ/ÑkqÓ1rÑkqÐfg°!°J±-Ð@VÑ2WÐX`Ó2aÐkqÑ1rÐtxð  AX€Gô  YØ‡G�G©Ó/© 1ˆQˆ~Ó¨Ñ/ÑkqÓ1rÑkqÐfg°!°J±-Ð@VÑ2WÐX`Ó2aÐkqÑ1rÐtyð  BY€Gô  ZØ‡M�M�%Ô˜"Ÿ-™-Ð(<Ô=¸r¿}¹}ÐM_Ô?`Ðbd×biÑbiÐjnÐvxÐbiÔbyÐ{}÷  |Eñ  |Eð  OPð  |Eô  |QÜ˜& !×$‰ˆˆ1Ø�_‰_˜T 1 a°Dˆ_Ó9ˆØ�J‘-  ;¡°°7±ˆaˆ1ˆô �q“6˜T’>‰a q¬¯©°Q¼¸A»¸q¹À$ÌcÔ)RÑ'SˆØ
�‰˜š!˜Q˜$™ ¢1 a 4¡¨!ªA¨q¨D©'¸SÀwÐV[ÐgjÐvð  HKð  Y^ˆô  	_Ø
�‰�x Ð"3Ñ 4Ð5°_ÀQÀ~ÑEVÐDWÐXÐcdˆÔeØ
�‰˜" 3ˆÔ'¨×):Ñ):¸9Ô)EÀrÇ{Á{ÐSWÐX[ÔG\Ð^`×^iÑ^iÐjnÐorÔ^sÐuw÷  vAñ  vAð  BFð  GJô  vKØ
�‰Öð %ð ×ÑÔ˜Ÿ™ C¨S˜Ô1°3·9±9¸Sµ>ùò 0ùÒ1rùÚ/ùÒ1rs   Á&JÁ8J
Â#JÂ5J
c                ó0  — d| D �cg c]}  }|d   |d   |d   j                  d«      j                  «       |d   j                  «       |d   j                  j                  «       |d   j                  d«      j                  «       d	œ‘Œ c}i}|d
z  j                  dt	        j
                  |d¬«      z   dz   d¬«       d}t        j                  j                  t        «       dz  |«      }|j                  d|«      }|dz  j                  |d¬«       y c c}w )NrJ  r,  r  r$  é   ru   r[   r%  )ÚbudgetÚactualÚposÚfaceÚedger%  zviewer_data.jszwindow.CAD_GRAPH_DATA=)Ú,Ú:)Ú
separatorsÚ;Úutf8©Úencodingu5  <!doctype html><meta charset="utf-8"><title>CAD graph resolutions</title>
<style>body{margin:0;background:#e8edf2;color:#15212b;font:14px sans-serif}#bar{position:fixed;z-index:2;padding:10px;background:#ffffffdd;border-radius:0 0 6px 0}canvas{display:block}label{margin-right:9px}</style>
<div id="bar"><label>Budget <select id="budget"></select></label><label><input id="wire" type="checkbox" checked> wireframe</label><label><input id="nodes" type="checkbox"> nodes</label><label><input id="curv" type="checkbox" checked> curvature</label><span id="info"></span></div>
<script src="../../datas_2/viewer/vendor/three.min.js"></script><script src="../../datas_2/viewer/vendor/OrbitControls.js"></script><script src="viewer_data.js"></script><script>
const D=window.CAD_GRAPH_DATA,sel=document.querySelector('#budget'), scene=new THREE.Scene(),cam=new THREE.PerspectiveCamera(45,innerWidth/innerHeight,.01,100),r=new THREE.WebGLRenderer({antialias:true});r.setClearColor(0xe8edf2);r.setSize(innerWidth,innerHeight);document.body.append(r.domElement);cam.up.set(0,0,1);cam.position.set(0,-1.4,.2);cam.lookAt(0,0,0);const controls=new THREE.OrbitControls(cam,r.domElement);controls.target.set(0,0,0);controls.update();scene.add(new THREE.HemisphereLight(0xffffff,.6,2));let group;D.graphs.forEach((g,i)=>sel.add(new Option(g.budget+' requested / '+g.actual+' actual',i)));function dispose(o){o.traverse(x=>{if(x.geometry)x.geometry.dispose();if(x.material){let a=Array.isArray(x.material)?x.material:[x.material];a.forEach(m=>m.dispose())}})}function draw(){if(group){scene.remove(group);dispose(group)}let g=D.graphs[sel.value], geo=new THREE.BufferGeometry();geo.setAttribute('position',new THREE.Float32BufferAttribute(g.pos.flat(),3));geo.setIndex(g.face.flat());geo.computeVertexNormals();let col=[],mx=Math.max(...g.curvature,1e-9);for(let x of g.curvature){let t=Math.min(1,x/mx);col.push(t,.1,.9-t)}geo.setAttribute('color',new THREE.Float32BufferAttribute(col,3));group=new THREE.Group();let mat=new THREE.MeshStandardMaterial({vertexColors:curv.checked,wireframe:wire.checked,side:THREE.DoubleSide,roughness:.72,color:curv.checked?0xffffff:0x7da9bd});group.add(new THREE.Mesh(geo,mat));if(nodes.checked){let pg=new THREE.BufferGeometry();pg.setAttribute('position',geo.getAttribute('position'));group.add(new THREE.Points(pg,new THREE.PointsMaterial({size:.009,color:0x15212b})));}scene.add(group);info.textContent=' '+g.actual+' actual nodes; requested budget is a node budget. Legend: blueâ†’magenta = discrete |mean curvature|; analytic values are masked and not rendered.'}for(let e of [sel,wire,nodes,curv])e.onchange=draw;addEventListener('resize',()=>{cam.aspect=innerWidth/innerHeight;cam.updateProjectionMatrix();r.setSize(innerWidth,innerHeight)});(function loop(){requestAnimationFrame(loop);controls.update();r.render(scene,cam)})();draw();</script>zdatas_2/viewer/vendorz../../datas_2/viewer/vendorzviewer.html)ÚroundÚtolistÚTÚ
write_textÚjsonÚdumpsÚosr?   Úrelpathr   rÄ   )rJ  Úout_dirrO  ÚpayloadÚhtmlÚvendor_paths         r   Ú_write_viewerrl    s8  € àñ lró	sñ lrÐfgð	 &'Ð'8Ñ%9ÀQÀ~ÑEVð ˜
‘m×)Ñ)¨!Ó,×3Ñ3Ó5¸qÀ¹z×?PÑ?PÓ?RØ˜‘×(Ñ(×/Ñ/Ó1ÀÀ+Á×@TÑ@TÐUVÓ@W×@^Ñ@^Ó@`ó	bð lrñ	sð t€Gð
 ÐÑ×+Ñ+Ð,DÄtÇzÁzÐRYÐfpÔGqÑ,qÐtwÑ,wð  CIÐ+ô  JðJ!€Dô
 —'‘'—/‘/¤%£'Ð,CÑ"CÀWÓM€KØ�<‰<Ð5°{ÓC€DØˆ}Ñ×(Ñ(¨¸Ð(Õ?ùòss   †BDc                ó„  — dd l }t        j                  «       }|j                  dd¬«       t	        | «      }t        |«      \  }}	}
|j                  d«      |j                  d«      z   dz  }t        t        j                  |j                  d«      |j                  d«      z
  «      «      }|dk  rt        d«      ‚t        |j                  «       «      }g }t        | «      |j                  «       |dœg dœ}|D �]Y  }t        j                  «       }t        t        |	«      t        dt        |dz  «      «      «      }|j!                  |«      }|j#                  «        |j%                  «        |j'                  «        t        |«      \  }}}t)        |||«      }t+        |||«      \  }}}t        j,                  |«      j/                  d	«      t1        |«      d
kD  z  }|d d …dd…fxx   |d d …d f   z  cc<   t3        |||«      \  }}}}||z
  |z  } t        j4                  | |||f«      j7                  t        j8                  «      }!t        j4                  t        j,                  | «      t        j:                  |d d …d f   dd	¬«      ||f«      }"g d¢|z   g d¢z   }#t=        ||«      \  }$}%t?        ||«      \  }&}'t        |j                  «       «      }(t        |«      })|)|kD  }*|*}+d },|+rD|j!                  d«      }-|-j%                  «        t        t        |-j@                  «      «      },|,|kD  }+i d|“d|“d|)“dt        t        |«      «      “d|*“dd“d|+r|,nd “d|+rdnd “d|&“d|'“dtC        |)|d   «      “dt        |d   d	k(  jE                  «       «      “dt        |d   dkD  jE                  «       «      “d t        |d d …df   jG                  «       «      “d!t        |d d …df   jG                  «       «      “d"|“d#|(“|(|z
  |z  t        j                  «       |z
  tI        «       d$œ¥}.t        jJ                  |d%|› d&�z  |j7                  t        j8                  «      | j7                  t        j8                  «      |j7                  t        j8                  «      |!|"t        jL                  |#d'¬(«      |d)   |d*   t        jL                  g d+¢d,¬(«      |jN                  j7                  t        jP                  «      |$|%|t        jR                  |)tT        ¬(«      ¬-«       |d.   jW                  |.«       |jW                  ||)| ||d)   |d d …df   |&d/œ«       �Œ\ t        t        |«      «      |d0<   t        t        |	«      «      |d1<   ||d2<   d3|d4<   |r|jY                  «       rt        |«      nd |d5<   t        j                  «       |z
  |d6<   tI        «       |d7<   |d8z  j[                  t]        j^                  |d¬9«      d:¬;«       |xs ta        «       d<z  }|j                  dd¬«       tc        ||d=z  «       te        ||«       |S )>Nr   T)r   Úexist_okrV   z mesh has zero bounding-box scale)Ú	center_mmÚscale_mm)ÚsourceÚnormalizationÚresolutionsr“   r   r‘   rY   r)   )Ú
pos_norm_xÚ
pos_norm_yÚ
pos_norm_zÚnormal_xÚnormal_yÚnormal_z)Úanalytic_k1_abs_1_per_mmÚanalytic_k2_abs_1_per_mmÚ"analytic_gaussian_signed_1_per_mm2Úrequested_node_budgetÚdecimator_target_trianglesr  Úactual_trianglesÚnode_budget_exceededÚnode_budget_notezYmeasured output count may differ because QEM accepts a triangle target, not a node targetÚconfirmed_qem_node_floorÚ
floor_notez;QEM minimum triangle request still retained this many nodesÚsurface_distance_mmÚsurface_distance_methodÚ
componentsr`   Úboundary_edgesra   Únonmanifold_edgesÚcurvature_valid_fractionÚ!analytic_curvature_valid_fractionÚanalytic_curvature_mappingÚsurface_area_mm2)Úarea_change_fractionÚ	elapsed_sÚpeak_process_memory_mbÚgraph_z.npzz<U48rD   r[   r\   )Ú	length_mmÚdirection_xÚdirection_yÚdirection_zÚ
normal_dotÚdihedral_radÚboundary_edgeÚfeature_edgez<U32)Úpos_mmr$  Únormalrª   Úfeature_validÚfeature_namesr[   r\   Úedge_feature_namesrW  Úoriginal_vertex_indexÚoriginal_vertex_distance_mmÚ&analytic_curvature_mapping_distance_mmÚtraining_validrs  )r,  r  r$  ru   r[   r%  r  rÿ   Úsource_trianglesÚsource_area_mm2zÈx includes distinct discrete mesh mean-curvature magnitude/absolute Gaussian and (when explicitly supplied) analytic principal/gaussian samples. STL normal orientation is not assumed globally outward.Úcurvature_provenanceÚexternal_curvature_inputÚtotal_elapsed_sr�  z
index.json©Úindentr]  r^  úresults/graphszcomparison.png)3r2   ÚtimeÚperf_counterÚmkdirrB   rT   ÚminrÝ   r   r!   r9   Úget_surface_arear5   ra  r6   rÀ   Úsimplify_quadric_decimationr<   r=   r>   r�   rº   r    Úallr/   r  rn   r#   r$   r™   r  rý   r7   rÁ   r-   rÛ   r   Úsavez_compressedrJ   rb  rq   rf   rt   r›   Úexistsrc  rd  re  r   rQ  rl  )/Ú	mesh_pathÚcurvature_pathrh  ÚbudgetsÚresults_dirr@   Ústartedrq  Úsource_vÚsource_frü   ÚcenterÚscaleÚsource_arearJ  ÚindexÚ	requestedÚt0Ú
target_triÚsimpler.   rQ   rš  r¡   Úbase_xÚ
base_validÚ
base_namesÚnormal_goodÚ
external_xÚexternal_validÚexternal_distanceÚexternal_noter$  rª   r›  ÚnamesÚoriginal_indexÚcorrespondence_mmr  Údistance_methodr¦   rU  ÚexceededÚfloorÚfloor_nodesÚminimumÚrecords/                                                  r   ÚpreparerÓ    sB  € ÛÜ×ÑÓ!€G 7§=¡=¸È =Ô#MÜ˜	Ó"€F¼LÈÓ<PÑ$9 H¨h¸Ø�l‰l˜1‹o §¡¨Q£Ñ/°1Ñ4€F¼eÄBÇFÁFÈ8Ï<É<ÐXYË?Ð]e×]iÑ]iÐjkÓ]lÑKlÓDmÓ>n°eØ�‚zœÐ$FÓGÐGÜ˜×/Ñ/Ó1Ó2€KØ#%€FÌ#ÈiË.Ðy÷  zGñ  zGó  zIð  W\ñ  l]ð  npñ  @q uÜˆ	Ü×ÑÓ ˆô œ˜X›¬¨A¬s°9¸q±=Ó/AÓ(BÓCˆ
Ø×3Ñ3°JÓ?ˆØ×*Ñ*Ô,¨f×.QÑ.QÔ.SÐU[×UrÑUrÔUtÜ# FÓ+‰ˆˆ1ˆf´I¸aÀÀFÓ4K¨TÜ);¸A¸qÀ$Ó)GÑ&ˆ�
˜Jô —k‘k &Ó)×-Ñ-¨aÓ0´J¸vÓ4FÈÑ4KÑLˆØ’1�a˜�c�6Ó˜kª!¨T¨'Ñ2Ñ2ÓÜGZÐ[iÐklÐntÓGuÑDˆ
�NÐ$5°}Ø�f‘H˜eÑ#ˆÜ�O‰O˜X v¨v°zÐBÓC×JÑJÌ2Ï:É:ÓVˆÜŸ™¬¯©°XÓ)>ÄÇ	Á	È+ÒVWÐY]ÐV]ÑJ^Ð`aÐhiÔ@jÐlvð  yGð  )Hó  IˆÚ^ÐakÑkò  oMñ  MˆÜ,BÀ8ÈQÓ,OÑ)ˆÐ)Ü$<¸VÀVÓ$LÑ!ˆ�/Ü�V×,Ñ,Ó.Ó/ˆ¼#¸a»&°Ø˜IÑ%ˆ¨x uØˆÙð ×8Ñ8¸Ó;ˆG¸W×=aÑ=aÔ=cÜœc '×"2Ñ"2Ó3Ó4ˆKØ )Ñ+ˆEð
fÐ)¨9ð 
fÐ6RÐT^ð 
fÐ`nÐpvð 
fØ$¤c¬#¨a«&£kð
fØ3IÈ8ð
fà$ð  'Bð
fð -¹U©kÈð
fð ÑafÑ ]Ðlpð	
fð
 (¨ð
fð
 4MÈoð
fð ¤¨F°D¸Ñ4HÓ Ið
fð L\Ô]`ÐbfÐgtÑbuÐyzÑbz×aÑaó  bBó  ^Cð
fð &¤s¨D°Ñ,?À!Ñ,C×+HÑ+HÓ+JÓ'Kð
fð NhÔinÐoyÒz{Ð}~Ðz~Ño÷  pEñ  pEó  pGó  jHð
fð 6´u¸^ÊAÈqÈDÑ=Q×=VÑ=VÓ=XÓ7Yð
fð \xð  zGð
fð % dð
fð FJÈKÑEWÐ[fÑDfÜ#×0Ñ0Ó2°RÑ7ÔSbÓSdò
fˆô 	×Ñ˜G¨¨y¨k¸Ð&>Ñ>ÀqÇxÁxÔPR×PZÑPZÓG[Ðfn×fuÑfuÔvx÷  wAñ  wAó  gBð  KQ÷  KXñ  KXô  Y[÷  Ycñ  Ycó  KdØ¨}ÌBÏJÉJÐW\ÐdjÔLkÐx|ð  ~Jñ  yKð  W[ð  \gñ  WhÜ/1¯z©zò  ;mð  u{ô  0|Ø!"§¡§¡¬B¯H©HÓ!5È^ð  zKØCTÜ+-¯8©8°FÄ$Ô+Gõ	Ið 	ˆmÑ×#Ñ# FÔ+Ø�‰¨)ÀVÐYaÐlmð  ~Bð  COñ  ~Pð  _eò  fgð  ijð  fjñ  _kð  yAñ  Bö  	Cð_ ô`  #¤3 x£=Ó1€EÐ
ÑÌsÔSVÐW_ÓS`ÓOa°5Ð9KÑ3Lð  JÐchÐizÑc{ð %o€EÐ
 Ñ!Ù?MÐR`×RgÑRgÔRi¬¨NÔ(;Ðos€EÐ
$Ñ%Ü#×0Ñ0Ó2°WÑ<€EÐ
ÑÜ&5Ó&7€EÐ
"Ñ#Øˆ|Ñ×'Ñ'¬¯
©
°5ÀÔ(CÈfÐ'ÔUØÒ9¤£Ð)9Ñ!9€K¸;×;LÑ;LÐUYÐdhÐ;LÔ;iÜ�˜Ð'7Ñ7Ô8¼-ÈÐP[Ô:\Ø€Lr   c                 ó  — t        j                  t        ¬«      } | j                  dt        t        «       dz  d¬«       | j                  dt        d d¬«       | j                  dt        t        «       d	z  ¬
«       | j                  dt        t        «       dz  ¬
«       | j                  dt        dt        t        «      d¬«       | j                  «       }|j                  xsE |j                  j                  «       t        «       dz  j                  «       k(  rt        «       dz  nd }t        |j                  ||j                  t        |j                   «      |j"                  «      }t%        t'        j(                  |d¬«      «       y )N)Údescriptionz--meshz analysis/results/design_fine.stlz+STL/mesh input (default reference CAD mesh))rï   ÚdefaultÚhelpz--curvaturez_Explicit analytic curvature NPZ corresponding to --mesh (not implicitly reused for changed CAD)z--outzdata_processed/graphs)rï   rÖ  z	--resultsr©  z	--budgetsÚ+z0Requested NODE budgets; output counts may differ)rï   ÚnargsrÖ  r×  z*analysis/results/cad_surface_curvature.npzrV   r§  )ÚargparseÚArgumentParserÚ__doc__Úadd_argumentr   r   rÀ   ÚlistÚDEFAULT_BUDGETSÚ
parse_argsr%  rA   r
   rÓ  rH   Útuplerµ  ÚresultsÚprintrd  re  )rÅ   r%   r%  Úsummarys       r   Úmainrå  W  sq  € Ü×Ñ¬GÔ4€AØ‡N�N�8¤$´³Ð8ZÑ0Zð  bO€Nô  PØ‡N�N�=¤t°Tð  Ab€Nô  cØ‡N�N�7¤¬u«wÐ7NÑ/N€NÔOÐQR×Q_ÑQ_Ð`kÔrvô  AFó  AHð  IYñ  AYÐQ_ô  RZØ‡N�N�;¤S°¼TÄ/Ó=Rð  ZL€Nô  MØ	�‰‹€Að —‘ò  nÐXY×X^ÑX^×XfÑXfÓXhÔmrÓmtð  vXñ  nX÷  mañ  maó  mcò  Yc¤£Ð(TÒ Tð  im€IÜ�a—f‘f˜i¨¯©´°a·i±iÓ0@À!Ç)Á)ÓL€GÌeÔTX×T^ÑT^Ð_fÐopÔTqÕNrr   Ú__main__)Úreturnr   )rç  r   )r%   ú
np.ndarrayrç  rè  )r.   rè  rç  rè  )r?   r   )rç  z)tuple[np.ndarray, np.ndarray, np.ndarray])r7   rè  ru   rè  rv   rè  rç  údict[str, np.ndarray])r.   rè  rQ   rè  r¡   ré  rç  z(tuple[np.ndarray, np.ndarray, list[str]])rR   rÀ   r`   rè  rç  rÀ   )rÈ   rÀ   rÉ   znp.random.Generatorrç  rè  )i N  )ró   rÀ   rç  z'tuple[dict[str, dict[str, float]], str])rÿ   rè  r7   rè  rç  ztuple[np.ndarray, np.ndarray])r?   úPath | Noner7   rè  rv   rè  rç  z5tuple[np.ndarray, np.ndarray, np.ndarray, str | None])rJ  úlist[dict[str, Any]]rH   r   rç  ÚNone)rJ  rë  rh  r   rç  rì  )r³  r   r´  rê  rh  r   rµ  ztuple[int, ...]r¶  rê  rç  zdict[str, Any])rç  rì  )"rÜ  Ú
__future__r   rÚ  rd  rf  r   r   rª  Úpathlibr   Útypingr   rë   r!   rß  r   r   r&   r/   rB   rT   r�   rº   rÁ   rÎ   rý   r  r  rQ  rl  rÓ  rå  rð   r   r   r   Ú<module>rð     s´   ðñõ #ã Û Û 	Û Û Û Ý Ý ã ð A€ó/óQóPó:óó"ó*óZ$TóN	,ótôhó*5óLó@Bó.@ð$ etð  QUô @óF
sð ˆzÒ™4�6Ðr   