Ë
    ·=»j•€  ã                  ó’  — d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	 ddl
Z
 e
j                  d«       ddlmZ ddlZddlmZ ddlmZ  ej*                  g d	¢«      Z ej*                  g d
¢«      Z ej*                  g d¢«      Z ej*                  g d¢«      Z ej*                  g d¢«      Zd(d„Zd)d„Zd*d„Zd+d„Zd,d„Z	 d-	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d.d„Z 	 d-	 	 	 d/d„Z!d0d1d„Z"d0d2d„Z#d3d4d„Z$d5d6d„Z%d3d7d„Z&d8d„Z'	 	 d9	 	 	 	 	 d:d„Z(d;d„Z)d<d„Z*d=d„Z+d>d„Z,d?d „Z-d@d!„Z.d@d"„Z/dAd#„Z0dBd$„Z1dCdDd%„Z2dEd&„Z3e4d'k(  r e3«        yy)Fa�  Honest CAD/scan representations for the Moltex POC.

This module deliberately keeps CAD-only inputs separate from post-process scans.
It uses the existing triangulated CAD graph as a mesh: rasterized pixels retain a
triangle id and barycentric coordinates, so all image fields are from one visible
front-most surface point.  It does not infer thickness, stress, defect labels, or
thermal histories.
é    )ÚannotationsN)ÚPath)ÚAnyÚIterableÚAgg)Údistance_transform_edt)ÚcKDTree)Úx_mmÚy_mmÚz_mmÚnormal_xÚnormal_yÚnormal_zÚnormal_turn_degÚcurvature_magnitude_per_mmÚgaussian_curvature_per_mm2Úcurvature_validÚthickness_mmÚthermal_max_cÚ
stress_mpa)Úmmr   r   Úunitr   r   Údegú1/mmú1/mm2Úboolr   ÚCÚMPa)Úx_nativeÚy_nativeÚz_nativer   r   r   Únn_spacing_nativeÚlocal_surface_variation)r
   r   r   Údepth_mmr   r   r   r   r   r   Ú
silhouetteÚdistance_to_boundary_pxÚnormal_orientation_to_viewÚ
visibilityr   r   r   )r   r   r   r   r   r   r   r   r   r   r   Úpxr   r   r   r   r   c                 óV   — t        t        «      j                  «       j                  d   S )Né   )r   Ú__file__ÚresolveÚparents© ó    õJ   /Users/bsk/Downloads/á„†á…©á†¯á„�á…¦á†¨á„‰á…³/ì „ì²˜ë¦¬/representations.pyÚ	repo_rootr2   2   s    € Ü”‹>×!Ñ!Ó#×+Ñ+¨AÑ.Ð.r0   c                óÂ   — | j                   j                  dd¬«       | j                  dd¬«      5 }t        j                  ||ddd¬«       d d d «       y # 1 sw Y   y xY w)	NT©r.   Úexist_okÚwúutf-8©ÚencodingFé   )Úensure_asciiÚindentÚ	sort_keys)ÚparentÚmkdirÚopenÚjsonÚdump)ÚpathÚvalueÚfs      r1   Ú	json_dumprF   6   sK   € Ø‡K�K×Ñ˜d¨TÐÔ2Ø	�‰�3 ˆÔ	)¨QÜ�	‰	�%˜¨°qÀDÕI÷ 
*×	)Ñ	)ús   ±AÁAc                ó”   — t        j                  t        j                  | «      ddd¬«      j                  t         j                  «      S )Nç        )ÚnanÚposinfÚneginf)ÚnpÚ
nan_to_numÚasarrayÚastypeÚfloat32)Úas    r1   Úfinite32rR   <   s1   € Ü�=‰=œŸ™ A›¨C¸ÀCÔH×OÑOÔPR×PZÑPZÓ[Ð[r0   c                ó  — t        j                  | d¬«      5 }|j                  D �ci c]  }|||   j                  «       “Œ }}ddd«       h d£}|j	                  «       z
  }|rt        dt        |«      › �«      ‚|S c c}w # 1 sw Y   Œ@xY w)z<Load the pre-existing CAD graph; no graph generator is used.F©Úallow_pickleN>   ÚfaceÚnormalÚpos_mmÚ	k1_per_mmÚ	k2_per_mmr   zCAD graph missing )rL   ÚloadÚfilesÚcopyÚkeysÚ
ValueErrorÚsorted)rC   ÚdÚkÚoutÚrequiredÚmissings         r1   Úload_cad_graphrf   @   s€   € ä	�‰� EÕ	*¨aØ'(§w¢wÓ/¡w !ˆq�!�A‘$—)‘)“+‰~ wˆÐ/÷ 
+âX€HØ˜Ÿ™›Ñ#€GÙÜÐ-¬f°W«oÐ->Ð?Ó@Ð@Ø€Jùò 0÷ 
+Ð	*ús   ˜B§A>ÁBÁ>BÂBc                óh  — t        | d   «      dk  rt        j                  g d¢«      nt        j                  g d¢«      }t        j                  || «      }|t        j                  j                  |«      z  }t        j                  | |«      }|t        j                  j                  |«      z  }||fS )z@Stable screen basis (u right, w up) for a camera-to-object axis.r:   gÍÌÌÌÌÌì?)rH   rH   ç      ð?)rH   rh   rH   )ÚabsrL   ÚarrayÚcrossÚlinalgÚnorm)ÚviewÚ	referenceÚur6   s       r1   Ú_view_basisrq   K   s   € ä-0°°a±«\¸BÒ->”—‘šÔ)ÄBÇHÁHÊ_ÓD]€IÜ
�‰�˜DÓ!€A 1¬¯	©	¯©°qÓ(9Ñ#9 1Ü
�‰��qÓ€A˜1¤§	¡	§¡¨qÓ 1Ñ1˜1Øˆaˆ4€Kr0   c	                ó®  — t        j                  | t         j                  ¬«      }	t        j                  |«      j                  d   dk(  r/t        j                  |t         j                  ¬«      j
                  n$t        j                  |t         j                  ¬«      }
t        j                  |t         j                  ¬«      }t        j                  |t         j                  ¬«      }|t         j                  j                  |«      z  }t        |«      \  }}|	|z  |	|z  |	|z  }}}t        |j                  «       «      t        |j                  «       «      }}t        |j                  «       «      t        |j                  «       «      }}t        |xs t        ||z
  ||z
  d«      dz  «      }|t        ||z
  ||z
  «      k  rt        d«      ‚||z   dz  ||z   dz  }}||dz  z
  ||dz  z   ||dz  z
  ||dz  z   f\  }}}}||dz
  z  }||z
  |z  }||z
  |z  }||f}t        j                  |d	t         j                  ¬«      }t        j                  |t         j                   t         j                  ¬«      }t        j                   g |¢d‘­t         j"                  ¬«      }t%        |
«      D �]‚  \  } }!||!   ||!   ||!   }$}#}"t        dt'        t        j(                  |"j                  «       d
z
  «      «      «      t        |dz
  t'        t        j*                  |"j                  «       d
z
  «      «      «      }&}%t        dt'        t        j(                  |#j                  «       d
z
  «      «      «      t        |dz
  t'        t        j*                  |#j                  «       d
z
  «      «      «      }(}'|%|&kD  s|'|(kD  r�Œ|#d   |#d   z
  |"d   |"d   z
  z  |"d   |"d   z
  |#d   |#d   z
  z  z   })t-        |)«      dk  r�ŒKt         j.                  |'|(dz   …|%|&dz   …f   \  }*}+|+d
z   }+|*d
z   }*|#d   |#d   z
  |+|"d   z
  z  |"d   |"d   z
  |*|#d   z
  z  z   |)z  },|#d   |#d   z
  |+|"d   z
  z  |"d   |"d   z
  |*|#d   z
  z  z   |)z  }-d|,z
  |-z
  }.|,dk\  |-dk\  z  |.dk\  z  }/|,|$d   z  |-|$d   z  z   |.|$d   z  z   }0||'|(dz   …|%|&dz   …f   }1|/|0|1kD  z  }2t        j0                  |2«      s�Œ2|0|2   |1|2<   ||'|(dz   …|%|&dz   …f   }3| |3|2<   ||'|(dz   …|%|&dz   …f   }4|,|2   |-|2   |.|2   c|4d   |2<   |4d   |2<   |4d   |2<   �Œ… |dk\  }5t        j                   g |¢d‘­t         j"                  ¬«      }6t        j                   g |¢d‘­t         j"                  ¬«      }7t        j                   |t         j"                  ¬«      }8t        j                   |t         j"                  ¬«      }9t        j                   |t2        ¬«      }:t        j4                  |5«      \  };}<t7        |;|<«      D ]ë  \  }=}>|
||=|>f      }!||=|>f   j9                  t         j                  «      }?|	|!   j
                  |?z  |6|=|>f<   ||!   j
                  |?z  }@t         j                  j                  |@«      }A|Ar@Az  nd|7|=|>f<   t        j:                  |?||!   «      |8|=|>f<   t        j:                  |?||!   «      |9|=|>f<   t3        t        j<                  ||!   «      «      |:|=|>f<   Œí d|8|: <   d|9|: <   t?        |5«      j9                  t         j"                  «      |5z  }Bt        j@                  |7|z  d	¬«      j9                  t         j"                  «      |5z  }Ci d|6“dtC        |«      |5z  “d|7“d|8“d|9“d|:“d|5“d|B“d|C“d|5“d|“d|“d|j9                  t         j"                  «      “d|j9                  t         j"                  «      “d |j9                  t         j"                  «      “d!t        j                  ||||gt         j"                  ¬«      “d"t        j                  |t         j"                  ¬«      “S )#zöOrthographically rasterize triangles with a largest-depth (front-most) z-buffer.

    ``view`` points from object toward camera.  The returned source_triangle and
    barycentric arrays enable exact backprojection to the source CAD triangle.
    ©Údtyper   é   rh   çR¸…ëQð?z3field_of_view_mm does not contain the projected CADr:   r+   éÿÿÿÿç      à?çê-�™—q=gH¯¼šò×z¾©.r   ©.r+   ©.r:   rH   ©ÚaxisÚxyz_mmr$   rW   r   r   r   r%   r&   r'   r(   Úsource_triangleÚbarycentricÚview_object_to_cameraÚscreen_uÚscreen_wÚorthographic_bounds_uw_mmÚpixel_pitch_mm)"rL   rN   Úfloat64ÚshapeÚint64ÚTrl   rm   rq   ÚfloatÚminÚmaxr_   ÚfullÚint32ÚinfÚzerosrP   Ú	enumerateÚintÚceilÚfloorri   ÚmgridÚanyr   ÚwhereÚziprO   ÚdotÚallr   ÚsumrR   )DrX   ÚfacesrW   Úcurvature_magnitudeÚgaussianr   rn   Ú
resolutionÚfield_of_view_mmÚprE   ÚnÚvrp   r6   ÚpuÚpwÚdepthÚu0Úu1Úw0Úw1ÚsideÚucÚwcÚpitchr)   Úpyrˆ   ÚsourceÚzbufÚbaryÚtiÚtriÚqxÚqyÚqzÚxminÚxmaxÚyminÚymaxÚdenomÚyyÚxxÚb0Úb1Úb2ÚinsideÚzzÚcurrentÚtakeÚssÚbbÚvisibleÚxyzÚnorÚcurv_magÚgaussÚcurv_okÚrowsÚcolsÚyÚxÚbÚnirm   Úsilhouette_distanceÚorientationsD                                                                       r1   Úrasterize_viewr×   S   s'  € ô 	�
‰
�6¤§¡Ô,€AÜ/1¯z©z¸%Ó/@×/FÑ/FÀqÑ/IÈQÒ/NŒ�
‰
�5¤§¡Ô)×+Ò+ÔTV×T^ÑT^Ð_dÔln×ltÑltÔTu€AÜ
�
‰
�6¤§¡Ô,€AÜ
�
‰
�4œrŸz™zÔ*€A¨A´·±·±ÀÓ1BÑ,B¨AÜ�q‹>�D€A€qØ˜‘E˜1˜q™5 ! a¡%ˆEˆ€Bô �2—6‘6“8‹_œe B§F¡F£H›oˆ€B¼¸b¿f¹f»h»ÌÈrÏvÉvËxË°2¨rÜÐ!Ò@¤S¨¨B©°°2±°sÓ%;¸DÑ%@ÓA€DØŒc�"�R‘%˜˜B™ÓÒÜÐNÓOÐOØ�‰e�Q‰Y˜˜B™ ™	ˆ€BØ˜˜Q™‘Y  4¨¡6¡	¨2¨d°1©f©9°b¸¸a¹±iÐ?�N€BˆˆB�Ø�J˜q‘LÑ!€EØ
ˆR‰%�‰€B˜b ™e U™]˜Ø˜Ð$€EÜ�W‰W�U˜B¤b§h¡hÔ/€FÜ�7‰7�5œ2Ÿ6™6˜'¬¯©Ô4€DÜ�8‰8�K�e�K˜Q‘K¤r§z¡zÔ2€Dô ˜Q—<‰ˆˆCØ˜‘W˜b ™g u¨S¡z�ˆBˆÜ˜œC¤§¡¨¯©«°©Ó 4Ó5Ó6¼¸JÀq¹LÌ#ÌbÏhÉhÐWY×W]ÑW]ÓW_Ð`bÑWbÓNcÓJdÓ8eˆdˆÜ˜œC¤§¡¨¯©«°©Ó 4Ó5Ó6¼¸JÀq¹LÌ#ÌbÏhÉhÐWY×W]ÑW]ÓW_Ð`bÑWbÓNcÓJdÓ8eˆdˆØ�$Š;˜$ š+ÙØ�A‘�r˜!‘u‘˜r !™u R¨¡U™{Ñ+¨r°!©u°R¸±U©{¸RÀ¹UÀ2ÀaÁ5¹[Ñ.IÑIˆÜˆu‹:˜ÒÙÜ—‘˜$˜t A™v˜+ t¨D°©F {Ð2Ñ3‰ˆˆBØ�"‰Wˆ˜2 ™7�bØ�!‰u�R˜‘U‰{˜R  1¡™XÑ&¨"¨Q©%°°1±©+¸¸2¸a¹5¹Ñ)AÑAÀUÑJˆØ�!‰u�R˜‘U‰{˜R  1¡™XÑ&¨"¨Q©%°°1±©+¸¸2¸a¹5¹Ñ)AÑAÀUÑJˆØ�‰V�B‰YˆØ˜‘+ "¨¡+Ñ.°"¸±+Ñ>ˆØ��1‘‰X˜˜2˜a™5™Ñ  2 b¨¡e¡8Ñ+ˆØ�t˜D ™F�{ D¨¨a© KÐ/Ñ0ˆØ˜˜g™Ñ&ˆÜ�v‰v�dŒ|ÙØ˜4™ˆ�‰Ø�D˜˜a™�K  d¨1¡f Ð,Ñ-ˆ¸"¨r°$©xØ�$�t˜A‘v�+˜t D¨¡F˜{Ð*Ñ+ˆØ?AÀ$¹xÈÈDÉÐSUÐVZÑS[Ð<ˆˆ6‰
�4Ñ˜"˜V™* TÑ*¨B¨v©J°tÓ,<ð/  ð0 ˜‰k€GÜ
�(‰(�;�U�;˜A‘;¤b§j¡jÔ
1€CÜ
�(‰(�;�U�;˜A‘;¤b§j¡jÔ
1€CÜ�x‰x˜¤R§Z¡ZÔ0€H¼"¿(¹(À5ÔPR×PZÑPZÔ:[°%Ü�h‰h�u¤DÔ)€GÜ—‘˜'Ó"�J€Dˆ$Ü�D˜$–‰ˆˆ1Ø��q˜!�t‘‰oˆ 4¨¨1¨¡:×#4Ñ#4´R·Z±ZÓ#@˜qØ�c‘F—H‘H˜q‘LˆˆAˆqˆD‰	Øˆs‰V�X‰X˜‰\ˆ¤"§)¡)§.¡.°Ó"4˜4Ù!%�B˜’I¨3ˆˆAˆqˆD‰	ÜŸ™ Ð#6°sÑ#;Ó<ˆ��A�‰Ü—f‘f˜Q ¨¡Ó.ˆˆa�ˆd‰äœRŸV™V O°CÑ$8Ó9Ó:ˆ��1�Šð  ð €HˆgˆXÑ°˜e W H™oô 1°Ó9×@Ñ@ÄÇÁÓLÈwÑVÐÜ—&‘&˜˜Q™ RÔ(×/Ñ/´·
±
Ó;¸gÑE€Kð	Ø�#ð	Ø!¤8¨D£>°GÑ#;ð	Ø=EÀsð	à$ hð	à0LÈeð	ð 	˜7ð	ð %1°'ð	ð <UÐVið	ð 	% kð		ð 4@Àð		ð
 	˜6ð	ð
 $1°$ð	ð 	  §¡¬"¯*©*Ó!5ð	ð 8BÀ1Ç8Á8ÌBÏJÉJÓCWð	ð ZdÐef×emÑemÔnp×nxÑnxÓeyð	ð 	$¤R§Z¡Z°°R¸¸RÐ0@ÌÏ
É
Ô%Sð	ð 	œ"Ÿ*™* U´"·*±*Ô=ð	ð 	r0   c                óö  — | d   | d   }}t        j                  ||z  ||z  z   «      }| j                  d||z  «      }t        j                  g d¢g d¢g d¢g d¢g d¢g d	¢gt         j                  ¬
«      }|€5t        t        j                  | d   d¬«      j                  «       d«      dz  }|D �cg c]!  }t        | d   | d   | d   ||| d   |||«	      ‘Œ# }	}|	d   D �
�ci c])  }
|
t        j                  |	D �cg c]  }||
   ‘Œ	 c}«      “Œ+ }}
}t        j                  |d   d   |d   d   |d   d   |d   |d   d   |d   d   |d   d   |d   |d   |d   |d   |d   |d   |d   t        j                  |d   «      t        j                  |d   «      t        j                  |d   «      gd¬«      j                  t         j                  «      }|d   }t        j                  ||||||||d   |d   t        j                  |«      t        j                  |«      ||t        j                  |«      t        j                  |«      t        j                  |«      t        j                  |«      gd¬«      j                  t        «      }|j                  ||t        t        t        j                  |t        ¬
«      t        j                   d|t         j                  ¬
«      d œ«       |S c c}w c c}w c c}}
w )!NrY   rZ   Úgaussian_signed_per_mm2)r+   r   r   )rw   r   r   )r   r+   r   )r   rw   r   )r   r   r+   )r   r   rw   rs   rX   r   r}   rh   rv   rV   rW   r   r   rz   r{   r|   r$   r   r   r%   r&   r'   r(   r+   é   )rÒ   Úfeature_validÚfeature_namesÚfeature_unitsÚtraining_validr¡   )rL   ÚsqrtÚgetrN   rP   r�   Úptpr×   ÚstackÚ
zeros_likerO   Ú	ones_liker   ÚupdateÚIMAGE_FEATURE_NAMESÚIMAGE_FEATURE_UNITSrŽ   )Úcadr    r¡   Úk1Úk2ÚmagrŸ   Ú
directionsr¤   Úrendersrb   Úrrc   rÒ   rÉ   Úvalids                   r1   Úmake_multiviewrð   ¬   sô  € à�Ñ˜s ;Ñ/ˆ€BÜ
�'‰'�"�R‘%˜"˜R™%‘-Ó
 €Cð �w‰wÐ0°"°R±%Ó8€HÜ—‘šW¢Xªg²hºwÂxÐPÔXZ×XbÑXbÔc€Jð ÐÜœrŸv™v c¨(¡m¸!Ô<×@Ñ@ÓBÀCÓHÈ4ÑOÐá`jólÙ`jÐ[\ô ˜c (™m¨S°©[¸#¸h¹-ÈÈhØ!Ð"3Ñ4°a¸ÐEUõWØ`jð ð là9@ÀºÔ
D¹°Aˆ1Œb�h‰h¡gÓ.¡g ˜˜!› gÑ.Ó/Ñ/¸€CÑ
Dä
�‰ØˆH‰�fÑ˜s 8™}¨VÑ4°c¸(±mÀFÑ6KÈSÐQ[É_ØˆH‰�fÑ˜s 8™}¨VÑ4°c¸(±mÀFÑ6KØÐ(Ñ)¨3Ð/KÑ+LÈcÐRcÑNdØˆLÑ˜3Ð8Ñ9¸3Ð?[Ñ;\Ð^aÐbnÑ^oÜ
�‰�c˜*‘oÓ&¬¯©°c¸*±oÓ(FÌÏÉÐVYÐZdÑVeÓHfðð ô	÷ ‰v”b—j‘jÓ!ð ð �,Ñ€GÜ�H‰HØ�˜' 7¨G°W¸gØÐÑ Ð$5Ñ 6¼¿¹ÀWÓ8MÜ
�‰�WÓ˜w¨´·±¸gÓ1FÜ
�‰�gÓ¤§¡¨gÓ 6¼¿¹ÀgÓ8Nð	ð
 ô÷
 ‰v”d‹|ð 
ð ‡J�J�Q¨ÔATÜ!4Ü"$§-¡-°¼tÔ"DÜ$&§G¡G¨AÐ/?ÄrÇzÁzÔ$RñTô Uð €Jùò-lùâ.ùÓ
Ds   Â0&K+Ã K5Ã9K0Ä	K5Ë0K5c                óÆ   — t        t        |«      t        | «      «      }t        j                  t        j                  j                  |«      j                  | |d¬«      «      S )zJStable without-replacement sample independent of dictionary/hash ordering.F)ÚsizeÚreplace)rŒ   r“   rL   ÚsortÚrandomÚdefault_rngÚchoice)r£   ÚcountÚseeds      r1   Údeterministic_sample_indicesrú   Ñ   sF   € ä”�E“
œC ›FÓ#€EÜ�7‰7”2—9‘9×(Ñ(¨Ó.×5Ñ5°a¸eÈUÐ5ÓSÓTÐTr0   c           
     óê  — t        j                  | d   t         j                  ¬«      }t        j                  | d   t         j                  ¬«      j                  }||   }dt         j
                  j                  t        j                  |dd…df   |dd…df   z
  |dd…df   |dd…df   z
  «      d¬	«      z  }t        j                  |dkD  «      st        d
«      ‚t         j                  j                  |«      }|j                  t        |«      t        |«      d||j                  «       z  ¬«      }|j                  t        |«      df«      }	t        j                   |	dd…df   «      }
t        j"                  d|
z
  |
d|	dd…df   z
  z  |
|	dd…df   z  g«      }t        j$                  d|||   «      |j'                  t         j(                  «      |j'                  t         j*                  «      fS )zLDeterministic area-uniform samples with triangle/barycentric correspondence.rX   rs   rV   rx   Nr+   r   r:   r}   z(CAD mesh has no non-degenerate trianglesT)rò   ró   r¢   ú
ni,nij->nj)rL   rN   r‡   r‰   rŠ   rl   rm   rk   r—   r_   rõ   rö   r÷   Úlenr“   rœ   rß   Úcolumn_stackÚeinsumrO   r�   rP   )rè   rø   rù   r¢   rV   rµ   ÚareaÚrngr±   rî   Úsrr³   s               r1   Úarea_uniform_surface_samplesr  ×   s‡  € ä
�
‰
�3�x‘=¬¯
©
Ô3€AÜ�:‰:�c˜&‘k¬¯©Ô2×4Ñ4€DØ
ˆD‰'€CØŒb�i‰i�n‰nœRŸX™X cª!¨A¨#¡h¨s²1°Q°3©xÑ&7¸ºQ¸q¸S¹À#ÂaÈÀcÁ(Ñ9JÓKÐRSˆnÓTÑT€DÜ�6‰6�$˜‘(ÔÜÐCÓDÐDÜ
�)‰)×
Ñ
 Ó
%€CØ�Z‰Zœ˜D›	¬¨E«
¸DÀDÈÏÉËÁOˆZÓT€FØ�
‰
”C˜“J �?Ó#€A¬"¯'©'°!²A°a°C±&«/ RÜ�?‰?˜A˜b™D " a¨ª!¨A¨#©¡h¡-°°A²a¸°c±F±Ð;Ó<€DÜ�9‰9�\ 4¨¨V©Ó5°v·}±}ÄRÇXÁXÓ7NÐPT×P[ÑP[Ô\^×\fÑ\fÓPgÐgÐgr0   c                óT  — d| vr§t        t        | d   «      |«      }| d   |   }d }d }|j                  t        j                  «      }| d   |   }| d   |   }t        j
                  | d   |   dz  | d   |   dz  z   «      }	| j                  d| d   | d   z  «      |   }
| d	   |   }d
}�nJt        | |«      \  }}}t        j                  | d   t        j                  ¬«      j                  |   }t        j                  d|| d   |   «      }|t        j                  t        j                  j                  |dd¬«      d«      z  }t        j                  d|| d   |   «      }t        j
                  | d   dz  | d   dz  z   «      }| j                  d| d   | d   z  «      }t        j                  d|||   «      }	t        j                  d|||   «      }
t        j                  | d	   |   d¬«      }d}t        j                   ||	d«      }	t        j                   ||
d«      }
t#        t        j$                  ||||	|
|t        j&                  t        |«      df«      g«      «      }t        j(                  |«      }|d d …d f   |d d …dd…f<   d|d d …df<   d|d d …dd …f<   t#        |«      t#        |«      ||t*        t,        |t        j&                  t        |«      t.        ¬«      t        j                  dt        j                  ¬«      t        j                  |«      dœ
}|�||d<   |S )NrV   rX   rW   r   rY   r:   rZ   rÙ   r   z5deterministic CAD graph node fallback (no face input)rs   rü   r+   T©r~   Úkeepdimsry   úni,ni->nr}   z,deterministic area-uniform triangle samplingrH   ru   é   é	   Fé
   é2(5)
rX   rW   rÒ   rÛ   rÜ   rÝ   r€   rÞ   Úsampling_seedÚsampling_methodr�   )rú   rý   rO   rL   r�   rß   rà   r  rN   r‰   rŠ   rÿ   Úmaximumrl   rm   r›   r˜   rR   rþ   r‘   ÚisfiniteÚCAD_FEATURE_NAMESÚCAD_FEATURE_UNITSr   )rè   rø   ÚixÚ
sample_posrµ   r³   r±   rW   Úturnrë   rŸ   rÎ   ÚmethodÚ
vertex_magÚvertex_gaussianrÒ   rï   Úresults                     r1   Ú
cad_pointsr  æ   s“  € Ø�SÑä)¬#¨c°(©mÓ*<¸eÓDˆØ˜‘] 2Ñ&ˆ
¨d¨¸4°DØ—‘œ2Ÿ8™8Ó$ˆ¨s°8©}¸RÑ/@ fÈÐM^ÑI_Ð`bÑIcÀ$Ü�g‰g�c˜+Ñ& rÑ*¨AÑ-¨c°+Ñ.>¸rÑ.BÀAÑ.EÑEÓFˆÐSV×SZÑSZÐ[tÐvyð  {Fñ  wGð  HKð  LWñ  HXñ  wXó  TYð  Z\ñ  T]Èð  ilð  m~ñ  ið  @Bñ  iCð  _fØHŠä#?ÀÀUÓ#KÑ ˆ
�F˜DÜ�j‰j˜˜V™¬B¯H©HÔ5×7Ñ7¸Ñ?ˆÜ—‘˜<¨¨s°8©}¸SÑ/AÓBˆÀFÌbÏjÉjÔY[×YbÑYb×YgÑYgÐhnÐuvð  BFÐYgó  ZGð  INó  OOñ  EOÀFÜ�y‰y˜ T¨3Ð/@Ñ+AÀ#Ñ+FÓGˆÜ—W‘W˜S Ñ-¨qÑ0°°[Ñ1AÀ1Ñ1DÑDÓEˆ
ÐY\×Y`ÑY`ÐazÐ|ð  ALñ  }Mð  NQð  R]ñ  N^ñ  }^ó  Z_ÀÜ�i‰i˜
 D¨*°S©/Ó:ˆÄrÇyÁyÐQ[Ð]aÐcrÐsvÑcwÓGx¸HÜ—&‘&˜Ð.Ñ/°Ñ4¸1Ô=ˆÐHv¸vÜ
�(‰(�7˜C Ó
%€C´"·(±(¸7ÀHÈcÓ2R xÜ”—‘ *¨f°d¸CÀÈ7ÔTV×T\ÑT\Ô^aÐbhÓ^iÐklÐ]mÓTnÐ!oÓpÓq€AÜ�K‰K˜‹N€E¨G²A°t°GÑ,<˜E¢! Q q S &™MÈD¸eÂAÀqÀD¹kÐbgÐRWÒXYÐ[]Ñ[^ÐX^ÑR_Ü  Ó,¼ÀÓ8HÈqÐchÜ0ÔCTØ!'¼2¿8¹8ÄCÈÃKÔW[Ô;\Ü!Ÿz™z¨(¼"¿(¹(ÔCÔXZ×XbÑXbÐciÓXjñl€Fð Ð°˜ Ñ.Ø€Mr0   c           	     óf  — t        j                  | t         j                  ¬«      }|j                  dk7  s |j                  d   dk7  st        |«      dk(  rt        d«      ‚t        j                  |«      j                  «       st        d«      ‚t        |«      }t        t        dt        |«      «      t        |«      «      }|j                  ||¬«      \  }}|dk(  r|d	d	…d	f   |d	d	…d	f   }}t        j                  |«      }t        j                  t        |«      «      }t        j                  t        |«      «      }	t        j                  t        |«      t         ¬«      }
t        j                  t        |«      t         ¬«      }t#        t        |«      «      D �]  }|||      ||   z
  }t         j$                  j'                  |j(                  |z  t        t        |«      d«      z  «      \  }}t        j*                  |dd	«      }t        |«      dk\  r||df   d
kD  r||df   dc|	|<   ||<   t        |«      dk\  sŒ¥t         j$                  j-                  |d¬«      dk\  sŒÊ|j/                  «       d
kD  sŒÞ|d	d	…df   ||<   |d   |j/                  «       z  ||<   d|
|<   �Œ
 t        j0                  |||	|g«      j3                  t         j4                  «      }t        j                  |t         ¬«      }d|d	d	…d	d…f<   |
d	d	…d	f   |d	d	…dd…f<   ||d	d	…df<   |
|d	d	…df<   t7        |«      |fS )zTLocal PCA descriptors in the original scan coordinate frame; normals are unoriented.rs   r:   r+   ru   r   z+scan points must be a non-empty [N,3] arrayz*scan points contain non-finite coordinates)rb   Nry   Tg»½×Ùß|Û=)ÚtolrÚ   r  )rL   rN   r‡   Úndimrˆ   rý   r_   r  r›   r	   rŒ   r�   r“   Úqueryrã   r‘   r   Úrangerl   ÚeighrŠ   ÚclipÚmatrix_rankrœ   rþ   rO   rP   rR   )ÚpointsÚ	neighborsr¢   Útreerb   ra   ÚnnÚnormalsÚ	variationÚspacingÚnormal_validÚspacing_validÚiÚqÚvalsÚvecsrÒ   rï   s                     r1   Úestimate_scan_featuresr/    s©  € ä
�
‰
�6¤§¡Ô,€AØ‡v�v�‚{�a—g‘g˜a‘j A’o¬¨Q«°1ªÜÐFÓGÐGÜ�;‰;�q‹>×ÑÔÜÐEÓFÐFÜ�1‹:€DÜŒC�”3�y“>Ó"¤C¨£FÓ+€AØ�J‰J�q˜AˆJÓ�E€A€rØˆA‚v�qš˜4˜‘y "¢Q t V¡*�"ˆqÜ�m‰m˜AÓ€G¬B¯H©H´S¸³VÓ,< 	ÌÏÉÔQTÐUVÓQWÓHX¸gÜ—8‘8œC ›F¬$Ô/€LÄÇÁÌ#ÈaË&ÔX\ÔA]°Ü”3�q“6�]ˆØˆb�‰e‰H�q˜‘t‰OˆÜ—Y‘Y—^‘^ A§C¡C¨!¡G¬c´#°a³&¸!«nÑ$<Ó=‰
ˆˆdÜ�w‰w�t˜Q Ó%ˆÜˆq‹6�QŠ;˜1˜Q˜q˜S™6 Eš>Ø+,¨Q¨q¨S©6°4Ð(ˆG�A‰J˜ aÑ(ô ˆq‹6�Q‹;œ2Ÿ9™9×0Ñ0°¸Ð0Ó>À!ÓCÈÏÉË
ÐUZÓHZØša ˜d™ˆG�A‰J°D¸±G¸d¿h¹h»jÑ4H Y¨q¡\Ð\`È,ÐWXË/ð ô 	�‰˜˜G W¨iÐ8Ó9×@Ñ@ÄÇÁÓL€AÜ�M‰M˜!¤4Ô(€E¸¨%²°"°1°"°©+È\ÒZ[Ð\`ÐZ`ÑMa¸eÂAÀaÈÀcÀE¹lØ€EŠ!ˆAˆ#�J¨\ ¢a¨ c¡
Ü�A‹;˜ÐÐr0   c                óô  — t        j                  | d¬«      5 }t        j                  |d   t         j                  ¬«      }d d d «       t	        t        «      |dt        t        t        |«      «      z   ¬«      }t        ||   «      \  }}t        ||   «      ||t        t        j                  dgdz  d	gdz  z   dd	gz   «      |j                  t         j                  «      t        j                  d
«      t        j                  d«      t        j                  t        |«      t        ¬«      t        j                  dt        t        t        |«      «      z   t         j                   ¬«      dœ
S # 1 sw Y   �Œ.xY w)NFrT   r"  rs   r  )rù   Únativeru   r   Úraw_scan_native_unregisteredT)
Ú
pos_nativerÒ   rÛ   rÜ   rÝ   Úsource_pointÚframeÚdiagnostic_post_processrÞ   r  )rL   r[   rN   r‡   rú   rý   rœ   ÚmapÚordr/  rR   ÚSCAN_FEATURE_NAMESrO   r�   r‘   r   r‰   )ÚcacheÚrun_idrø   ra   Úrawr  rÒ   rï   s           r1   Úscan_pointsr=    s  € Ü	�‰� UÕ	+¨qÜ�j‰j˜˜8™¬B¯J©JÔ7ˆ÷ 
,ä	%¤c¨#£h°¸HÄsÌ3ÌsÐTZÓK[ÓG\Ñ<\Ô	]€BÜ% c¨"¡gÓ.�H€A€uÜ" 3 r¡7Ó+°!ÀeÜ/Ä"Ç*Á*ÈhÈZÐXYÉ\Ð[aÐZbÐcdÑZdÑMdÐfnÐpvÐewÑMwÓBxØŸI™I¤b§h¡hÓ/¼"¿*¹*ÐEcÓ:dÜ')§z¡z°$Ó'7Ì2Ï8É8ÔTWÐXZÓT[ÔcgÔKhÜŸZ™Z¨´3´s¼3ÀÓ7GÓ3HÑ(HÔPR×PXÑPXÔYñ	[ð [÷	 
,Ñ	+ús   ˜)E-Å-E7c                óˆ  — t        j                  | d   t         j                  ¬«      }t        j                  | d   t         j                  ¬«      j                  }g }g }g }t        |«      D �]W  \  }}||   }	t        dt        t        j                  t        j                  t         j                  j                  |	dd…df   |	ddd…f   z
  d¬«      «      |z  «      «      «      }
t        j                  |
|
f«      \  }}|j                  «       |j                  «       }}||z   |
k  }||   ||   }}t        j                  |dz   |
z  |dz   |
z  d||z   d	z   |
z  z
  g«      }|j                  ||	z  «       |j                  t        j                  t!        |«      |t         j"                  «      «       |j                  |«       �ŒZ t        j$                  |«      j'                  t         j(                  «      }t        j$                  |«      }t        j$                  |«      j'                  t         j(                  «      ||d
œS )uí   Deterministic interior triangle samples at approximately one per pitchÂ².

    This prevents sparse voxel occupancy from being merely CAD graph vertex
    occupancy.  Every sample retains its source triangle and barycentric weights.
    rX   rs   rV   r+   Nrw   r}   gUUUUUUÕ?gUUUUUUå?)rX   r€   r�   )rL   rN   r‡   r‰   rŠ   r’   r�   r“   r”   rl   rm   ÚindicesÚravelrþ   ÚappendrŽ   rý   r�   ÚconcatenaterO   rP   )rè   Úpitch_mmr¢   rV   r"  Ú	trianglesÚbarysr´   Úidsr,  r£   ÚiiÚjjÚkeeprÓ   r³   Útri_ids                    r1   Útriangle_surface_samplesrK  *  sÊ  € ô 	�
‰
�3�x‘=¬¯
©
Ô3€A¼B¿J¹JÀsÈ6Á{ÔZ\×ZbÑZbÔ<c×<eÑ<e°TØ!€FÀ 9Ð_aÀUÜ˜T—?‰ˆˆCØˆc‰Fˆœ˜Aœs¤2§7¡7¬2¯6©6´"·)±)·.±.ÀÂ1ÀTÀ6ÁÈ1ÈTÒRSÈVÉ9ÑATÐ[]°.Ó2^Ó+_Ð`hÑ+hÓ#iÓjÓk�Aä—‘˜Q ˜FÓ#‰ˆˆB¨b¯h©h«j¸"¿(¹(»*¨ RÈRÐRTÉWÐWXÉ[ÀdÐceÐfjÑckÐmoÐptÑmuÐ^`ÐZ\Ü�O‰O˜b ™f a™Z¨"¨S©&°!©°Q¸¸2¹¸c¹	À1±}±_ÐEÓFˆØ�‰�a˜!‘eÔ˜i×.Ñ.¬r¯w©w´s¸1³v¸rÄ2Ç8Á8Ó/LÔMÈuÏ|É|Ð\]Îð #ô �>‰>˜%Ó ×'Ñ'¬¯
©
Ó3€D¼b¿n¹nÈYÓ>W°VÜ—n‘n VÓ,×3Ñ3´B·J±JÓ?ÐTZÐkoÑpÐpr0   c                óê  — t        j                  | d   t         j                  ¬«      }|j                  d«      |j	                  d«      }}t        j
                  ||z
  d«      }|�t        |«      n|j	                  «       t        |«      z  }|dk  rt        d«      ‚|€Lt        j
                  dt        j                  ||z  «      j                  t         j                  «      «      }	|}
nŽt        j                  |t         j                  ¬«      }	|	j                  dk7  st        j                  |	dk  «      rt        d«      ‚t        j                  ||	|z  d	z   kD  «      rt        d
«      ‚||z   |	|z  z
  dz  }
t        | |«      }|d   j                  t         j                  «      }t        j                  ||
z
  |z  «      j                  t         j                  «      }t        j                  |dk  «      st        j                  ||	kD  «      rt        d«      ‚t        j                   ||	dz
  «      }|d d …df   |	d   |d d …df   |	d   |d d …df   z  z   z  z   }t        j"                  |dd¬«      \  }}}t        j$                  ||	d   z  ||	d   z  |	d   z  ||	d   |	d   z  z  g«      j                  t         j                  «      }t        j                  | d   t         j&                  ¬«      j(                  |d      }|d   j                  t         j                  «      }t        j*                  d|| d   |   «      }|t        j
                  t         j,                  j/                  |dd¬«      d«      z  }t        j*                  d|| d   |   «      }t        j0                  | d   dz  | d   dz  z   «      }| j3                  d| d   | d   z  «      }t        j4                  | d   |   d¬«      }t        j6                  |t        j*                  d|||   «      d«      }t        j6                  |t        j*                  d|||   «      d«      }t9        |«      }t        j:                  |df«      }t        j:                  |«      }t        j:                  |«      }t        j:                  |«      } t        j:                  |«      }!t         j<                  j?                  |||«       t         j<                  j?                  |||«       t         j<                  j?                  |||«       t         j<                  j?                  | ||«       t         j<                  j?                  |!||j                  t        «      «       |t        j
                  t         j,                  j/                  |dd¬«      d«      z  }||z  }|!dkD  }"||"xx   |!|"   z  cc<   | |"xx   |!|"   z  cc<   tA        t        j$                  t        jB                  |«      ||||| |"t        j:                  |df«      g«      «      }#t        jD                  |#tF        ¬«      }$|"d d …d f   |$d d …dd …f<   d|$d d …d f<   d!|$d d …d"d …f<   i d#|“d$|#“d%|$“d&t        j                  g d'¢«      “d(|	“d)|j                  t         jH                  «      “d*|j                  t         jH                  «      “d+|
j                  t         jH                  «      “d,t        j                  |t         jH                  ¬«      “d-|	|z  |z
  j                  t         jH                  «      “d.|d   “d/|d   “d0|j                  t         j                  «      “d1t        j                  |t         j                  ¬«      “d2t        j                  d«      “d3t        j                  d!«      “d4t        j                  d5«      “d6t        j:                  |tF        ¬«      i¥S )7NrX   rs   r   g:Œ0âŽyE>zvoxel pitch must be positiver+   )ru   z1grid_shape must contain three positive dimensionsç�íµ ÷Æ°>z)fixed voxel grid does not contain the CADr:   z*surface sample lies outside the voxel gridT)Úreturn_inverseÚreturn_countsrV   r€   r�   rü   rW   r  ry   r  r   rY   rZ   rÙ   r   r}   rH   ru   rÚ   é   Fr	  Úvoxel_coordsrÒ   rÛ   rÜ   )Úsurface_occupancyÚsurface_sample_countr   r   r   r   r   r   r   r   r   r   Ú	grid_dimsÚbbox_min_mmÚbbox_max_mmÚgrid_origin_mmÚvoxel_pitch_mmÚgrid_padding_mmÚsurface_sample_source_triangleÚsurface_sample_barycentricÚsurface_sample_voxel_indexÚlongest_axis_resolutionÚsurface_onlyÚsolid_occupancyÚoccupancy_methodz6deterministic triangle interior samples at voxel pitchrÞ   )%rL   rN   r‡   rŒ   r�   r  r‹   r“   r_   r”   rO   r�   rˆ   r—   rK  r•   ÚminimumÚuniquerþ   r‰   rŠ   rÿ   rl   rm   rß   rà   r›   r˜   rý   r‘   ÚaddÚatrR   Úonesrä   r   rP   )%rè   r]  rX  Ú
grid_shaper¢   Úbbox_loÚbbox_hiÚspanr¯   ÚdimsÚoriginÚsamplesr  ÚcoordÚlinearrb  Úinvrø   Úvoxrµ   r³   Úsample_normalÚsample_turnr  r  Úsample_validÚ
sample_magÚsample_gaussianÚnvoxrm   r  rë   rŸ   Ú
curv_countÚ
curv_validrÒ   rï   s%                                        r1   Úsurface_voxelsry  <  sà  € ô 	�
‰
�3�x‘=¬¯
©
Ô3€AØ—u‘u˜Q“x §¡ q£ˆW€GÜ�:‰:�g˜g‘o tÓ,€DØ%3Ð%?ŒE�.Ô!ÀTÇXÁXÃZÔPSÐTkÓPlÑEl€EØ�‚zœÐ$BÓCÐCØÐÜ�z‰z˜!œRŸW™W T¨%¡ZÓ0×7Ñ7¼¿¹ÓAÓBˆØ‰ä�z‰z˜*¬B¯H©HÔ5ˆØ�:‰:˜Ò¤§¡¨¨q©Ô!1¼ÐDwÓ9xÐ3xÜ�6‰6�$˜˜e™ dÑ*Ñ*Ô+´:Ð>iÓ3jÐ-jØ˜'‘/ $ u¡*Ñ,¨aÑ/ˆÜ& s¨EÓ2€GØ˜Ñ"×)Ñ)¬"¯*©*Ó5€Jô �H‰H�j Ñ'¨Ñ.Ó/×6Ñ6´r·x±xÓ@€EÜ	‡v�vˆe�a‰iÔœBŸF™F 5¨4¡<Ô0¼
ÐCoÓ8pÐ2pÜ�J‰J�u˜d 1™fÓ%€EØ’1�a�4‰[˜4 ™7 Eª!¨Q¨$¡K°$°q±'¸%ÂÀ1À¹+Ñ2EÑ$EÑFÑF€FÜŸ™ 6¸$ÈdÔSÑ€FˆC�Ü
�/‰/˜6 D¨¡GÑ+¨f°d¸1±g©oÀÀaÁÑ-HÈ&ÐSWÐXYÑSZÐ[_Ð`aÑ[bÑSbÑJcÐdÓ
e×
lÑ
lÔmo×muÑmuÓ
v€CÜ
�*‰*�S˜‘[¬¯©Ô
1×
3Ñ
3°GÐ<MÑ4NÑ
O€CÐX_Ð`mÑXn×XuÑXuÔvx÷  wAñ  wAó  YBÐQUÜ—I‘I˜l¨D°#°h±-ÀÑ2DÓE€MÀ}ÔXZ×XbÑXbÔce×clÑcl×cqÑcqÐrð  GHð  SWÐcqó  dXð  Z_ó  Y`ñ  H`À}Ü—)‘)˜J¨¨cÐ2CÑ.DÀSÑ.IÓJ€KÜ—‘˜˜[Ñ)¨1Ñ,¨S°Ñ-=¸qÑ-@Ñ@ÓA€JÐUX×U\ÑU\Ð]vÐx{ð  }Hñ  yIð  JMð  NYñ  JZñ  yZó  V[À?Ü—6‘6˜#Ð/Ñ0°Ñ5¸AÔ>€LÜ—‘˜,¬¯	©	°*¸dÀJÈsÁOÓ(TÐVYÓZ€JÜ—h‘h˜|¬R¯Y©Y°zÀ4ÈÐY\ÑI]Ó-^Ð`cÓd€OÜˆv‹;€DœrŸx™x¨¨q¨	Ó2˜¼2¿8¹8ÀD»>°DÔQS×QYÑQYÐZ^ÓQ_È3Ôln×ltÑltÐuyÓlzÐaiô  JL÷  JRñ  JRð  SWó  JXð  }GÜ‡F�F‡I�Iˆd�C˜Ô'¬¯©¯©°4¸¸kÔ)JÜ‡F�F‡I�Iˆc�3˜
Ô#¤R§V¡V§Y¡Y¨x¸¸oÔ%NÔPR×PVÑPV×PYÑPYÐZdÐfiÐkw×k~Ñk~ô  @Eó  lFô  QGØŒB�J‰J”r—y‘y—~‘~ d°¸T�~ÓBÀEÓJÑJ€DÈDÐTYÉMÈDØ˜a‘€J  Z£°J¸zÑ4JÑ!J£ÈHÐU_ÓL`ÐdnÐoyÑdzÑLzÓL`Ü”—‘¤"§'¡'¨$£-°¸¸dÀCÈÐS]Ô_a×_gÑ_gÐimÐopÐhqÓ_rÐ!sÓtÓu€AÜ�L‰L˜¤$Ô'€E¸ÂAÀdÀFÑ9K¨ªq°!°A°#¨v©Ð[_ÈUÒSTÐVWÐSWÉ[ÐpuÐafÒghÐjkÑjlÐglÑamð\ˆN˜Cð \  að \¨¸%ð \ØœRŸZ™Zò  )Kó  Lð\à˜ð\à,¨g¯n©n¼R¿Z¹ZÓ.Hð\àJWÐY`×YgÑYgÔhj×hrÑhrÓYsð\ð ˜fŸm™m¬B¯J©JÓ7ð\ð :JÌ2Ï:É:ÐV[Ôce×cmÑcmÔKnð\ð   U¡
¨4¡×7Ñ7¼¿
¹
ÓCð	\ð
 -¨gÐ6GÑ.Hð\ð
 KgÐhoÐp}Ñh~ð\ð
 A]ð  _b÷  _iñ  _iô  jl÷  jrñ  jró  _sð\ð &¤r§z¡zÐ2IÔQS×QYÑQYÔ'Zð\ð œBŸJ™J tÓ,ð\ð /@ÄÇÁÈEÓARð\ð UgÔhj×hrÑhrð  tló  imð\ð oô  AC÷  AIñ  AIð  JNô  VZô  A[ñ\ð \r0   c                ó  — t        t        t        | d   «      «      }| d   j                  d   }t	        j
                  |g|¢­t        j                  ¬«      }t	        j
                  |g|¢­t        ¬«      }| d   }| d   j                  |d d …|d d …df   |d d …df   |d d …df   f<   | d   j                  |d d …|d d …df   |d d …df   |d d …df   f<   ||| d	   | d   t	        j                  d
«      t	        j                  d«      dœS )NrT  rÒ   r+   rs   rQ  r   r:   rÛ   rÜ   TF)rÒ   rÛ   rÜ   rT  r^  r_  )
Útupler7  r“   rˆ   rL   r‘   rP   r   rŠ   rN   )Úsparserj  ÚchannelsrÒ   rï   Úcs         r1   Údense_surface_tensorr  n  s  € Ü””S˜& Ñ-Ó.Ó/€D¸FÀ3¹K×<MÑ<MÈaÑ<P°Ü
�‰�(Ð"˜TÑ"¬"¯*©*Ô5€A¼r¿x¹xÈÐHYÐTXÑHYÔaeÔ?f°uØˆ~Ñ€AØ&,¨S¡k§m¡m€A‚aˆŠ1ˆaˆ4‰�!’A�q�D‘'˜1šQ ˜T™7Ð"Ñ#Ø*0°Ñ*A×*CÑ*C€EŠ!ˆQŠq�!ˆt‰W�aš˜1˜‘g˜q¢ A ™wÐ
&Ñ'Ø U¸VÀOÑ=TÐciÐjuÑcvÜŸJ™J tÓ,ÄÇÁÈEÓARñTð Tr0   c                óˆ  — t        j                  | j                  d¬«      «      }t        |«      }t        |j	                  «       D ��ch c]#  }|d   D ]  }|d   |j                  dd«      f’Œ Œ% c}}«      }t        j                  t        |«      t        |«      ft        j                  ¬«      }t        j                  |t        ¬«      }t        |«      D �	�
ci c]  \  }	}
|
|	“Œ
 }}	}
t        |«      D ]Y  \  }	}||   d   D ]I  }||d   |j                  dd«      f   }|j                  d«      €Œ/t        |d   «      d	c||	|f<   ||	|f<   ŒK Œ[ |d
   }|j                  d«      |j                  d«      z
  }|d
   |d   j                      }dt        j"                  j%                  t        j&                  |d d …df   |d d …df   z
  |d d …df   |d d …df   z
  «      d¬«      j)                  «       z  }t        j*                  g d¢«      }t        j*                  g |¢|‘t        |«      ‘|d   j,                  d   ‘t        j                  ¬«      }t        j*                  |«      ||t        j*                  |D ��cg c]  \  }}|› d|› d�‘Œ c}}«      t        j.                  |d    t        |«      d«      |t        j0                  |t        j.                  |d    t        |«      d«      gd«      t        j0                  |t        j2                  t        |«      t        |«      ft        «      gd«      t        j                  t        |«      t        ¬«      t        j                  t        |«      t        ¬«      t        j*                  t        j4                  dt        |«      ddœ«      «      dœS c c}}w c c}
}	w c c}}w )Nr7   r8   rÏ   Úchannelr   Ú rs   rD   TrX   r   rV   rx   r+   r:   r}   )Úcad_bbox_x_mmÚcad_bbox_y_mmÚcad_bbox_z_mmÚcad_surface_area_mm2Úcad_node_countÚcad_triangle_countz [Ú]z-none; one design/two runs; labels unavailable)Ú
design_idsÚrunsÚsplit)r;  Ú	process_xÚprocess_feature_validÚprocess_feature_namesÚ
geometry_xÚgeometry_feature_namesrÒ   rÛ   Úlabel_availablerÞ   Úsplit_metadata)rA   ÚloadsÚ	read_textr`   Úvaluesrà   rL   r‘   rý   rP   rã   r   r’   r‹   r�   rŒ   rŠ   rl   rm   rk   rœ   rN   rˆ   ÚrepeatrB  re  Údumps)Úprocess_pathrè   r<  Úrun_idsÚrunrî   r}  r–  Úpresentr+  r~  ÚlookupÚjr¢   rj  rµ   r   Ú	geo_namesÚgeor£   rp   s                        r1   Úprocess_tabularr¡  x  sp  € Ü
�*‰*�\×+Ñ+°WÐ+Ó=Ó
>€CÜ�S‹k€GÜÀCÇJÁJÄLÔfÁL¸SÐZ]Ð^dÔZeÐUV˜˜)™ a§e¡e¨F°BÓ&7Ò8ÐZeÐ8ÀLÒfÓg€HÜ�X‰X”s˜7“|¤S¨£]Ð3¼2¿:¹:ÔF€FÔRT×R_ÑR_Ð`fÔnrÔRsÈÜ(¨Ô2Ô3Ñ2‘t�q˜!ˆa�‰dÐ2€FÑ3Ü˜GÖ$‰ˆˆ3Ø�S‘˜&Ô!ˆAØ˜˜)™ a§e¡e¨F°BÓ&7Ð8Ñ9ˆAØ�u‰u�W‹~Ñ)Ü.3°A°g±JÓ.?ÀÐ+��q˜!�t‘˜g a¨ dšmñ "ð %ð
 	ˆH‰€A˜aŸe™e A›h q§u¡u¨Q£xÑ/�tØ
ˆh‰-˜˜F™Ÿ™Ñ
&€C¨r´"·)±)·.±.ÄÇÁÈ#ÊaÐPQÈcÉ(ÐSVÒWXÐYZÐWZÑS[ÑJ[Ð]`ÒabÐcdÐadÑ]eÐfiÒjkÐlmÐjmÑfnÑ]nÓAoÐvw°.Ó2x×2|Ñ2|Ó2~Ñ/~¨Ü—
‘
ò  Oó  P€IÜ
�*‰*Ð@�tÐ@˜TÐ@¤3 q£6Ð@¨3¨v©;×+<Ñ+<¸QÑ+?Ð@ÌÏ
É
Ô
S€CÜ—j‘j Ó)¸ÐY`Ü%'§Z¡ZÉÔ0RÉÁ#À!ÀA°A°3°b¸¸¸1²ÈÒ0RÓ%SÔce×clÑclÐmpÐquÑmvÔx{ð  }Dó  yEð  GHó  dIØ&/´b·n±nÀfÌbÏiÉiÐX[Ð\`ÑXaÔcfÐgnÓcoÐqrÓNsÐEtÐvwÓ6xÜŸ^™^¨W´b·g±g¼sÀ7»|ÌCÐPSËHÐ>UÔW[Ó6\Ð,]Ð_`ÓaÜ!Ÿx™x¬¨G«¼DÔAÔUW×U]ÑU]Ô^aÐbiÓ^jÔrvÔUwÜ Ÿj™j¬¯©À1ÌcÐRYËlð  fUñ  5Vó  *Wó  XñYð Yùó gùã3ùó 1Ss   Á	(N2
ÃN8É>N>c           	     óX  — t        j                  | t        ¬«      }t        j                  |t        ¬«      }|j                  dk7  s©|j                  dk  sš|j                  d   t        |«      k7  st        |«      dk  sqt        j                  |«      j                  «       rNt        j                  |«      j                  «       r+t        j                  t        j                  |«      dk  «      rt        d«      ‚t        j                  ||d¬«      }t        j                  |d¬«      }t        j                  |d¬«      t        j                  |d«      t        j                  t        j                  | d«      d¬«      |t        j                  t        j                   |«      d¬«      dœS )	a@  Extract real history features only when aligned time and field samples are supplied.

    fields is [T,...]. cooling_rate_per_s is the most negative d(field)/dt,
    and temporal_gradient_max_per_s is max absolute d(field)/dt.  No thermal
    values are produced by this pipeline because input histories are absent.
    rs   r+   r   r:   zQtime_s must be finite/strictly increasing and fields must be finite [T,...], T>=2r}   rH   )r�   Úcooling_rate_per_sÚmax_cooling_rate_per_sÚ!minimum_temporal_derivative_per_sÚtemporal_gradient_max_per_s)rL   rN   r‹   r  rˆ   rý   r  r›   r—   Údiffr_   ÚgradientrŒ   r�   ra  r  ri   )Útime_sÚfieldsÚtrQ   ÚrateÚmin_derivatives         r1   Úthermal_history_featuresr®  �  s  € ô 	�
‰
�6¤Ô'€A¬R¯Z©Z¸ÄeÔ-L¨Ø	�‰�!Š�q—v‘v ’z Q§W¡W¨Q¡Z´3°q³6Ò%9¼SÀ»VÀaºZÜ—‘˜A“×"Ñ"Ô$¬B¯K©K¸«N×,>Ñ,>Ô,@ÄBÇFÁFÌ2Ï7É7ÐSTË:ÐYZÉ?ÔD[ÜÐlÓmÐmÜ�;‰;�q˜! !Ô$€DÜ—V‘V˜D qÔ)€NÜ—6‘6˜! !Ô$Ü"$§*¡*¨^¸SÓ"AÜ&(§f¡f¬R¯Z©Z¸¸¸sÓ-CÈ!Ô&LØ1?Ü+-¯6©6´"·&±&¸³,ÀQÔ+Gñ	Ið Ir0   c                ó  — t        | |j                  «       D ��ci c]W  \  }}|t        t        j                  |«      j
                  «      t        t        j                  |«      j                  «      dœ“ŒY c}}|dœ«       y c c}}w )N)rˆ   rt   )ÚarraysÚ
provenance)rF   ÚitemsÚlistrL   rN   rˆ   Ústrrt   )rC   r°  r±  rb   r¤   s        r1   Ú_schemarµ  £  s”   € ÜˆdÐv|÷  wCñ  wCô  wEô   Fñ  wEÑorÐopÐqr ¬T´"·*±*¸Q³-×2EÑ2EÓ-FÔQTÔUW×U_ÑU_Ð`aÓUb×UhÑUhÓQiÑ#jÑ jð  wEò   Fð  V`ñ  aõ  bùó   Fs   šABc                óp  — | j                   j                  dd¬«       t        j                  | fi |¤Ž | j	                  d«      }t        |||«       t        | «      t        |«      |j                  «       D ��ci c].  \  }}|t        t        j                  |«      j                  «      “Œ0 c}}dœS c c}}w )NTr4   z.schema.json)ÚnpzÚschemar°  )r>   r?   rL   Úsavez_compressedÚwith_suffixrµ  r´  r²  r³  rN   rˆ   )rC   r°  r±  r¸  rb   r¤   s         r1   Ú	_save_npzr»  §  sš   € Ø‡K�K×Ñ˜d¨TÐÔ2´B×4GÑ4GÈÑ4WÐPVÒ4WØ×Ñ˜nÓ-€F¬w°v¸vÀzÔ/RÜ�t“9¬¨F«Ðhn×htÑhtÔhvÔ?wÑhvÑadÐabÐcdÀÄ4ÌÏ
É
ÐSTË×H[ÑH[ÓC\Ñ@\ÐhvÒ?wÑxÐxùÓ?ws   Á93B2
c           
     óF  — t        j                  ddd¬«      \  }}g d¢}| d   | d      }t        |«      rt        t	        j
                  |d«      «      nd	}t        d«      D ]Ý  }t        j                  j                  | d
   |    | d   |   «      }t        j                  j                  | d   |    | d   |   «      }	|d|f   j                  |d¬«       |d|f   j                  |	ddt        |d«      ¬«       |d|f   j                  ||   «       |d|f   j                  d«       |d|f   j                  d«       Œß |d   j                  d«       |d   j                  d«       |j                  «        |j                  |d¬«       t        j                   |«       y )Nr:   rÚ   )é   é   ©Úfigsize)z+Xz-Xz+Yz-Yz+Zz-Zr   r   éc   rh   r(   r$   r   Úviridis)Úcmapr+   Úmagmary   )rÃ  ÚvminÚvmaxÚoff)r   r   z
depth (mm))r+   r   z|curvature| (1/mm)é–   ©Údpi)ÚpltÚsubplotsrý   r‹   rL   Ú
percentiler  ÚmaÚmasked_whereÚimshowr�   Ú	set_titler~   Ú
set_ylabelÚtight_layoutÚsavefigÚclose)
ÚmvrC   ÚfigÚaxÚnamesÚ	good_curvÚcmaxr+  ra   r~  s
             r1   Ú_plot_imagesrÜ  ­  s'  € Ü�l‰l˜1˜a¨Ô1�G€CˆÒ;_°5ØÐ/Ñ0°Ð4EÑ1FÑG€IÜ25°i´.Œ5”—‘˜y¨"Ó-Ô.Àc€DÜ�1ŽXˆÜ�E‰E×Ñ  <Ñ 0°Ñ 3Ð3°R¸
±^ÀAÑ5FÓGˆÌRÏUÉU×M_ÑM_ÐacÐduÑavÐwxÑayÐ`yÐ{}ð  [ñ  |\ð  ]^ñ  |_ó  N`ÈØ
ˆ1ˆQˆ3‰�‰�q˜yˆÔ)¨2¨a°¨c©7¯>©>¸!À'ÐPQÔX[Ð\`ÐbgÓXh¨>Ô+iÐkmÐnoÐpqÐnqÑkr×k|Ñk|ð  ~Cð  DEñ  ~Fô  lGð  IKð  LMð  NOð  LOñ  IP÷  IUñ  IUð  V[ô  I\ð  ^`ð  abð  cdð  adñ  ^e÷  ^jñ  ^jð  kpõ  ^qð ð €s�G×Ñ�|Ô$ b¨¡g×&8Ñ&8Ð9MÔ&NÐPS×P`ÑP`ÔPbÐdg×doÑdoÐptÐz}ÐdoÔd~ô  AD÷  AJñ  AJð  KNõ  AOr0   c                ó®  — g d¢}t        j                  ddd¬«      \  }}| d   d   }t        |j                  |«      D ]Ý  \  }\  }}||dv r| d	   d   nd
z  }	| |   d   }
t        j
                  j                  |	 |
«      }|dv r^t	        j                  |	«      rIt	        j                  t	        j                  |
|	   «      d«      }|j                  d«      r| |dœnd|dœ}ni } |j                  |fddi|¤Ž |j                  |«       |j                  d«       Œß |j                  «        |j                  |d¬«       t        j                   |«       y )N))r$   r§   )r   z|curvature|)r   z
Gaussian K)r'   u   normalÂ·view)r&   zsilhouette distance)r   zcurvature validr:   ru   )r
  r  r¿  r(   r   >   r   r   r   TrÁ  rŸ   )rÅ  rÆ  rÃ  rÂ  rÇ  rÈ  rÉ  )rË  rÌ  r™   ÚflatrL   rÎ  rÏ  r—   rÍ  ri   Ú
startswithrÐ  rÑ  r~   rÓ  rÔ  rÕ  )rÖ  rC   r^   r×  rØ  ÚmaskrQ   rb   Útitlerï   r–  Úshownr,  Úlimitss                 r1   Ú_plot_channelsrä  ·  sP  € ò L€DÜ�l‰l˜1˜a¨Ô1�G€Cˆ¸"¸\Ñ:JÈ1Ñ:M°4Ü˜2Ÿ7™7 DÖ)‰ˆ‰)ˆ1ˆUØ°AÐ9uÑ4u˜Ð,Ñ-¨aÒ0Ð{ñ  AˆØ�A‘�q‘ˆ¤2§5¡5×#5Ñ#5°u°f¸fÓ#E˜5ØÐLÑLÔQS×QWÑQWÐX]ÔQ^Ü—‘œbŸf™f V¨E¡]Ó3°RÓ8ˆAÐ^_×^jÑ^jÐkuÔ^vÈQÈBÐXYÒCZð  FGð  QRñ  }S¹&ØˆfØˆ�‰�Ñ1˜YÐ1¨&Ò1°1·;±;¸uÔ3EÀqÇvÁvÈeÅ}ð *ð ×ÑÔ˜Ÿ™ D¨c˜Ô2´C·I±I¸cµNr0   c           
     óÐ  — t        j                  d¬«      }t        | d«      D ]‰  \  }}|j                  dd|d¬«      }|d   }|j	                  |d d …df   |d d …df   |d d …d	f   d|d
   d d …df   d¬«       |j                  dt        |d   «      › �«       |j                  |d   «       Œ‹ |j                  «        |j                  |d¬«       t        j                  |«       y )N)é   é   r¿  r+   ru   Ú3d©Ú
projectionrQ  r   r:   rÒ   rÚ   rÄ  )Úsr~  rÃ  zsurface voxels r]  rT  rÈ  rÉ  )rË  Úfigurer’   Úadd_subplotÚscatterrÑ  r“   Úset_box_aspectrÓ  rÔ  rÕ  )ÚvoxelsrC   r×  r+  r¤   rQ   r~  s          r1   Ú_plot_voxelsrñ  Ä  s  € Ü
�*‰*˜VÔ
$€CÜ˜ Ö#‰ˆˆ!Ø�O‰O˜A˜a ¨dˆOÓ3ˆ¸¸>Ñ9J°QØ	�	‰	�!’A�a�C‘&˜š1˜Q˜3™ ¢! A #¡¨¨Q¨s©V²A°a°C©[¸gˆ	ÔFÈÏÉÐVeÔfiÐjkð  mFñ  kGó  gHð  fIð  UJô  IKð  MN÷  M]ñ  M]ð  ^_ð  `kñ  ^lõ  Mmð $ð ×ÑÔ˜Ÿ™ D¨c˜Ô2´C·I±I¸cµNr0   c           	     ót  — | d   dfg|D �cg c]  }|d   t        |d   «      d d f‘Œ c}z   }t        j                  dt        |«      z  df¬«      }t	        |d«      D ]›  \  }\  }}|j                  dt        |«      |d	¬
«      }	|	j                  |d d …df   |d d …df   |d d …df   d¬«       |	j                  |«       |	j                  t        j                  t        j                  |d¬«      d«      «       Œ� |j                  «        |j                  |d¬«       t        j                  |«       y c c}w )NrX   zCAD (mm)r3  r5  é   rç  r¿  r+   rè  ré  r   r:   rx   )rë  r}   rM  rÈ  rÉ  )r´  rË  rì  rý   r’   rí  rî  rÑ  rï  rL   r  rá   rÓ  rÔ  rÕ  )
ÚcadpÚscansrC   rë  Úsetsr×  r+  r¢   rá  rQ   s
             r1   Ú_plot_pointsr÷  Ì  sb  € Ø�(‰^˜ZÐ(Ð)Ñ^cÓ,dÑ^cÐYZ¨a°©o¼sÀ1ÀWÁ:»ÈsÐPRÐ?SÒ-TÐ^cÑ,dÑd€DÜ
�*‰*˜a¤# d£)™m¨QÐ/Ô
0€CÜ   aÖ(‰ˆ‰)ˆ1ˆUØ
�/‰/˜!œC ›I a°4ˆ/Ó
8ˆ¸!¿)¹)ÀAÂaÈÀcÁFÈ1ÊQÈqÈSÉ6ÐRSÒTUÐVWÐTWÑRXÐ[]¸)Ô:^Ð`a×`kÑ`kÐlqÔ`rÐtu÷  uEñ  uEô  FH÷  FPñ  FPô  QS÷  QWñ  QWð  XYð  _`ô  Qað  bfó  Fgõ  uhð )à×ÑÔ˜Ÿ™ D¨S˜Ô1´3·9±9¸Sµ>ùò	 -es   ŒD5c                óö  — t        | «      } | dz  }| dz  }| dz  }|j                  dd¬«       t        |dz  «      }ddd	d
dœ}g g g g dœ}|D ]‹  }	t        |t	        |	«      «      }
|dz  d|	› d�z  }|d   j                  t        ||
|t	        |	«      ddœz  «      «       t        |
|d|	› d�z  «       t	        |	«      t        |«      k(  sŒ}t        |
|dz  «       Œ� t        ||«      }|d   j                  t        |dz  dz  ||ddiz  «      «       g }t        |j                  d«      «      D ]m  }|j                  j                  d«      }t        |||«      }|j                  |«       |d   j                  t        |dz  d|› d�z  |d|› d�ddddœ«      «       Œo t!        |||d z  «       g }d!D ]ˆ  }	t#        ||	«      }|j                  |«       |d"   j                  t        |d"z  d#|	› d�z  ||d$|	d%œz  «      «       |	d&k(  sŒU|d"   j                  t        |d"z  d'z  t%        |«      |dd(d)œz  «      «       ŒŠ t'        ||d*z  «       t)        |d+z  |«      }|d,   j                  t        |d,z  d-z  |d.d/d0d1d2œ«      «       |j+                  «       D ]  \  }}t-        ||z  d3z  ||d4œ«       Œ t-        |d3z  t        |j                  d5«      «      D �cg c]  }t/        |«      ‘Œ c}|g d6¢d7œ«       |S c c}w )8Nzanalysis/resultsÚdata_processedzresults/representationsTr4   zcad_graph.npzzanalysis/results/cad_graph.npzzCAD millimetreszexisting CAD graph triangleszFscans are separate diagnostic representations and training_valid=false)Ú
cad_sourceÚunitsÚmeshÚpost_scan_leakage)Úimagesr"  rð  Útabularrþ  Úcad_multiview_z.npzzlargest object-to-camera depth)r    Úz_bufferÚsix_view_depth_curvature_z.pngz!feature_channel_contact_sheet.pngr"  zcad_surface_points.npzÚkindzCAD-only pre-processz*_all_merge_pointcloud_full.npzz_all_merge_pointcloud_full.npzÚscan_z_diagnostic.npzzanalysis/results/z0raw cache native frame; no CAD transform applied)r±   r5  r6  Únot_pre_process_predictorzpoint_sample_comparison.png)é    é@   é€   rð  Úcad_surface_sparse_z&not filled solid; CAD is nonwatertight)rR  r]  r  zcad_surface_dense_32.npzznot filled solid)Úbounded_dense_tensorrR  zsparse_voxel_resolutions.pngzprocess.jsonrÿ  zprocess_and_geometry.npzzanalysis/results/process.jsonz1pre-process vector + fixed CAD geometry summariesÚunavailablez-one design, two runs; no generalization split)r±   ÚscopeÚlabelsrŒ  z
index.json)Úfamilyr²  z*.png)z>CAD source mesh is nonwatertight; all voxels are surface-only.zjNo thickness, thermal histories, stress, defect labels, or validated scan-to-CAD transform were available.zVRaw scans remain in their own native frames and are diagnostic post-process data only.)ÚplotsÚinputÚlimitations)r   r?   rf   rð   r“   rA  r»  rÜ  rŒ   rä  r  r`   ÚglobÚnameÚremovesuffixr=  r÷  ry  r  rñ  r¡  r²  rF   r´  )ÚrootÚresolutionsÚpoint_countr±   rc   r  rè   r±  ÚindexÚresrÖ  ÚdestÚcprõ  r:  r›  Úsprð  ÚsvÚtabr  ÚentriesrÒ   s                          r1   Úpreparer   Ô  s  € Ü�‹:€D Ð%7Ñ 7�v¸tÐDTÑ?T¸Ð^bÐc|Ñ^|ÐV[Ø	‡K�K˜ t€KÔ,Ü
˜ Ñ/Ó
0€CØ @ÐK\ð  gEð  \dñ  e€JØ8:ÀbÐTVÐceÑ-f€EÛˆÜ˜C¤ S£Ó*ˆ°3°x±<À.ÐQTÐPUÐUYÐ@ZÑ3Z¨DØˆh‰×Ñœy¨¨r°:ÌsÐSVËxð  fFñ  AGñ  4Gó   Hô  	IÜ�R˜Ð!:¸3¸%¸tÐDÑDÔEÜˆs‹8”s˜;Ó'Ó'¬¸¸EÐBeÑ<eÕ)fð	 ô
 
�C˜Ó	%€B u¨X¡×'=Ñ'=¼iÈÈHÉÐUmÑHmÐoqÐs}ð  BHð  I_ð  A`ñ  t`ó  ?aô  (bØ
€EÜ˜Ÿ™Ð$EÓFÖGˆØ�j‰j×%Ñ%Ð&FÓGˆÜ˜  [Ó1ˆ°5·<±<ÀÔ3CØˆh‰×Ñœy¨¨X©¸¸c¸UÀ/Ð6RÑ)RÐTVÐduÐvyÐuzð  {Yð  cZð  dVð  rvð  TXñ  YYó   Zõ  	[ð Hô ��U˜EÐ"?Ñ?Ô@Ø€FÛˆÜ˜#˜cÓ"ˆ F§M¡M°"Ô$5°u¸X±×7MÑ7MÌiÐX[Ð\dÑXdÐgzÐ{~Ðzð  @Dð  fEñ  YEð  GIð  KUð  mUð  qtñ  Xuñ  Kuó  Ovô  8wØ�‹7�E˜(‘O×*Ñ*¬9°S¸±\ÐB\Ñ5\Ô^rÐsuÓ^vð  yCð  ^bð  wIñ  FJñ  yJó  ,Kõ  Lð ô �˜Ð=Ñ=Ô>Ü˜˜~Ñ-¨cÓ2€C°E¸)Ñ4D×4KÑ4KÌIÐVYÐZcÑVcÐd~ÑV~ð  @Cð  Nmð  wjð  uBð  L{ñ  D|ó  M}ô  5~Ø Ÿ;™;ž=‰ˆ�¬)°C¸±J¸|Ñ4KÐW]ÐfmÑMnÕ*o˜=Üˆe�LÑ ¼VÀEÇJÁJÈwÓDWÔ=XÓ,YÑ=X¸¬S°­VÐ=XÑ,YÐdnò  @Jñ  #Kô  LØ€Lùò -Zs   ËK6
c                 óî  — t        j                  d¬«      } | j                  dt        t	        «       ¬«       | j                  ddt
        ddg¬	«       | j                  d
t
        d¬«       | j                  «       }t        |j                  |j                  |j                  «      }t        t        j                  |j                  «       D ��ci c]  \  }}|t        |«      “Œ c}}d¬«      «       y c c}}w )Nz5Prepare CAD-only and diagnostic-scan representations.)Údescriptionz--root)ÚtypeÚdefaultz--resolutionsÚ+r  é   )Únargsr#  r$  z--point-counté    F)r;   )ÚargparseÚArgumentParserÚadd_argumentr   r2   r“   Ú
parse_argsr   r  r  r  ÚprintrA   r˜  r²  rý   )ÚapÚargsr  rb   r¤   s        r1   Úmainr0  ñ  sê   € Ü×ÑÐ+bÔc€BØ‡O�O�H¤4´³€OÔ=¸r¿¹ÈÐfiÔpsð  Bð  CFð  ~G¸ô  @Hð  JL÷  JYñ  JYð  Ziô  psð  }Að  JYô  JBØ	�‰‹€D¤¨¯©°4×3CÑ3CÀD×DTÑDTÓ!U˜&Ü	Œ$�*‰*¨&¯,©,¬.Ô9©.¡3 1 Q�aœ˜A›‘h¨.Ò9ÈÔ
NÕOùÓ9s   ÃC1Ú__main__)Úreturnr   )rC   r   rD   r   r2  ÚNone)rQ   ú
np.ndarrayr2  r4  )rC   r   r2  údict[str, np.ndarray])rn   r4  r2  útuple[np.ndarray, np.ndarray])N)rX   r4  r�   r4  rW   r4  rž   r4  rŸ   r4  r   r4  rn   zIterable[float]r    r“   r¡   úfloat | Noner2  r5  )rè   r5  r    r“   r¡   r7  r2  r5  )r  )r£   r“   rø   r“   rù   r“   r2  r4  )rè   r5  rø   r“   rù   r“   r2  z)tuple[np.ndarray, np.ndarray, np.ndarray])r(  )rè   r5  rø   r“   r2  r5  )é   )r"  r4  r#  r“   r2  r6  )r:  r   r;  r´  rø   r“   r2  r5  )rè   r5  rC  r‹   r2  r5  )NN)
rè   r5  r]  r“   rX  r7  rf  ztuple[int, int, int] | Noner2  r5  )r|  r5  r2  r5  )r™  r   rè   r5  r2  r5  )r©  r4  rª  r4  r2  r5  )rC   r   r°  r5  r±  údict[str, Any]r2  r3  )rC   r   r°  r5  r±  r9  r2  r9  )rÖ  r5  rC   r   r2  r3  )rð  úlist[dict[str, np.ndarray]]rC   r   r2  r3  )rô  r5  rõ  r:  rC   r   r2  r3  ))r  r&  r(  )r  r   r  zIterable[int]r  r“   r2  zdict[str, list[dict[str, Any]]])r2  r3  )5Ú__doc__Ú
__future__r   r)  rA   Úpathlibr   Útypingr   r   Ú
matplotlibÚuseÚmatplotlib.pyplotÚpyplotrË  ÚnumpyrL   Úscipy.ndimager   Úscipy.spatialr	   rN   r  r  r9  ræ   rç   r2   rF   rR   rf   rq   r×   rð   rú   r  r  r/  r=  rK  ry  r  r¡  r®  rµ  r»  rÜ  rä  rñ  r÷  r   r0  Ú__name__r/   r0   r1   Ú<module>rG     sõ  ðñõ #ã Û Ý ß  ã Ø €
‡�ˆuÔ Ý Û Ý 0Ý !ð �B—J‘Jò  ó Ð ð
 �B—J‘Jò  ó Ð ð  �R—Z‘Zò !ó Ð ð !�b—j‘jò "ó Ð ð !�b—j‘jò "ó Ð ó/óJó\óóð NRðVØðVØ)ðVØ3=ðVà#ðVà/9ðVàLVðVð ðVð (+ðVð ?KðVð ó	Vðt 59ð"Ø%1ð"Ø=Ró"ôJUôhôô6ô:	[óqð& 37Ø=Að/\Ø#/ð/\à:ð/\àF[ó/\ódTóYó.Ió(bóyóOó
CóCóBôó:Pð ˆzÒ™4�6Ðr0   