Ë
    jø¨j²H  ã                  óÌ  — d Z ddlmZ ddlZddlZddlZddlmZ ddlZ	ddl
mZ ddlZddlmZ ddlmc mZ ddlZ ej$                  d«       ddlmZ ddlmZmZmZ dd	lmZ ed
z  Zedz  Zedz  Zedz  ZdZ  e	jB                  g d¢«      Z" e	jB                  g d¢«      Z#d„ Z$d„ Z%d„ Z&d„ Z'd„ Z( G d„ dejR                  «      Z*d„ Z+d„ Z,d„ Z-d„ Z.d„ Z/d„ Z0e1dk(  r e0«        yy)z`Prepared graph_6000 (5,925 actual nodes) weak-label diagnostic: normal baseline vs dihedral GNN.é    )ÚannotationsN)ÚPath)ÚcKDTree)ÚnnÚAgg)ÚROOTÚfixed_physical_normalizeÚsplit_embedded_units)Úseed_everythingÚdihedral_gnnÚinput_processedÚmodelÚoutputsg      >@)Ú
pos_norm_xÚ
pos_norm_yÚ
pos_norm_zÚnormal_xÚnormal_yÚnormal_zÚvertex_area_mm2Úmean_incident_angle_radÚmean_curvature_abs_1_per_mmÚ gaussian_curvature_abs_1_per_mm2Úboundary_nodeÚfeature_nodeÚtopological_degreeÚanalytic_k1_abs_1_per_mmÚanalytic_k2_abs_1_per_mmÚ"analytic_gaussian_signed_1_per_mm2Úcad_k1_signed_1_per_mmÚcad_k2_signed_1_per_mmÚcad_mean_H_signed_1_per_mmÚcad_gaussian_K_1_per_mm2Úcad_curvedness_1_per_mmÚcad_shape_index)Ú	length_mmÚdirection_xÚdirection_yÚdirection_zÚ
normal_dotÚdihedral_radÚboundary_edgeÚfeature_edgec                 óš   — t        t        dz  «      } | t        j                  vr t        j                  j	                  d| «      nd  dd l}|S )Nu	   ì „ì²˜ë¦¬r   )Ústrr   ÚsysÚpathÚinsertÚ
cad_graphs)Úpr3   s     údihedral_gnn/run_experiment.pyÚcgr6      s9   € Ü„tˆKÑÓ€°¼#¿(¹(Ñ1BœŸ™Ÿ™¨¨1Ô-ÈøÛØÐó    c                 óP
  — t         dz  } t        j                  | d¬«      5 }|j                  D �ci c]  }|||   “Œ
 }}ddd«       d   j	                  d«      }|d   j	                  d«      }|d   j	                  d«      }|d	   j	                  t
        «      }|d
   j	                  d«      }|d   j	                  d«      }	|	j                  «       }
|
dd…dfxx   dz  cc<   |
dd…dfxx   t        j                  z  cc<   t        |«      dk7  rt        dt        |«      › �«      ‚t        j                  t         dz  d¬«      }t        |d   «      j                  |d¬«      \  }}||d   |   z  j                  d«      }|dk  t        j                  |«      dkD  z  t        j                  |d   |   «      z  t        j                  |d   |   «      z  }t        j                  |dk\  dd«      }|d   |   |z  }|d   |   |z  }t        j                   ||«      }t        j"                  ||«      }||z   dz  }||z  }t        j$                  ||z  ||z  z   dz  «      }dt        j                  z  t        j&                  ||z   ||z
  «      z  }t        j(                  ||||||f   j	                  d«      }d|| <   t        j(                  ||f   }t        j(                  |t        j*                  |dd…df   dd«      f   }t,        j/                  dd¬ «       t1        |«      }|j3                  |j	                  d«      |t4        j	                  d!«      ¬"«       t        j6                  t,        d#z  fi |¤Ž t        j6                  t,        d$z  |j	                  d«      |j	                  d«      |j	                  d«      |j	                  d«      |j	                  d«      |j	                  d«      ||j	                  d«      |j	                  d«      ¬%«
       d&dt9        |d'   j:                  d   «      dd(dt=        |j?                  «       «      t9        |j                  «       «      t9        | j                  «       «      d)d*d+d,œd-œ}t,        d.z  jA                  tC        jD                  |dd¬/«      d0¬1«       |||t        j(                  tG        |t4        «      |j	                  d«      f   j	                  d«      ||	|
|d'   j	                  d2«      |d3œ	S c c}w # 1 sw Y   �ŒÞxY w)4zEOne prepared ~6k CAD graph only: requested 6,000, actual 5,925 nodes.ú$data_processed/graphs/graph_6000.npzF©Úallow_pickleNÚpos_mmÚf4ÚnormalÚxÚfeature_validÚ
edge_indexÚi8Ú	edge_attrr   iè  é   i%  z+graph_6000 expected 5925 actual nodes, got z*analysis/results/cad_surface_curvature.npzÚ	points_mmé   ©ÚworkersÚparameter_normalsé   gš™™™™™é?Ú	k1_per_mmÚ	k2_per_mmg      ð?g      ð¿é   é   T©ÚparentsÚexist_okz<U48)r?   r@   Úfeature_nameszprepared_graph_5925.npzz&dihedral_signed_curvature_features.npz)	r    r!   r"   r#   r$   r%   Úorientation_validÚmapping_distance_mmr*   ép  Úfacez_saved edge_index derives from saved faces; face dihedral remains the two-adjacent-face quantityzÔnearest STEP analytic sample <3 mm and abs(prepared normal dot STEP parameter normal) >0.8; both k values are multiplied by sign(dot) into prepared-normal convention, then ordered k1>=k2; invalid signs are maskedu[   H=(k1+k2)/2; K=k1*k2; curvedness=sqrt((k1Â²+k2Â²)/2); shape-index=(2/pi)*atan2(k1+k2,k1-k2)z„sign is meaningful only under this local oriented correspondence; use dihedral at sharp creases, where smooth curvature is undefined)Úcoverage_fractionÚvalid_countÚinvalid_countÚ
valid_ruleÚformulasÚcaveat)Úrequested_node_budgetÚactual_node_countÚtriangle_countÚsource_graphÚtopologyÚnode_padding_or_duplicationÚsigned_curvature_mappingz#prepared_graph_5925_provenance.json©Úensure_asciiÚindentÚutf8©ÚencodingÚi4)	Úposr>   ÚrawÚnodeÚedgeÚerawÚearV   Úmeta)$r   ÚnpÚloadÚfilesÚastypeÚboolÚcopyÚpiÚlenÚRuntimeErrorr   ÚqueryÚsumÚabsÚisfiniteÚwhereÚmaximumÚminimumÚsqrtÚarctan2Úc_ÚrepeatÚINPUTÚmkdirÚdictÚupdateÚNAMESÚsavez_compressedÚintÚshapeÚfloatÚmeanÚ
write_textÚjsonÚdumpsr	   )ÚsourceÚaÚkÚzÚvÚnr?   Úmaskrn   ro   rp   ÚcÚdÚixÚdotÚokÚorientÚbÚk1Úk2ÚHÚKÚCÚSÚextraÚaugrq   s                              r5   Úgraphr©      sm
  € äÐ3Ñ3€Ü‡g�gˆf %Õ(¨AÀÇÂÓ0IÁ¸A°°1°Q±4±À¨aÐ0I×(Ø€X�;×Ñ�dÓ€˜a ™k×0Ñ0°Ó6˜A¸¸3¹¿¹ÀtÓ9L°qÐRSÐTcÑRd×RkÑRkÔlpÓRqÈTÐwxð  zFñ  xG÷  xNñ  xNð  OSó  xTÐrvð  Z[ð  \gñ  Zh÷  Zoñ  Zoð  ptó  Zuð  UYð  y}÷  yBñ  yBó  yDð  vxð  EGò  HIð  JKð  HKó  ELð  NRñ  ERó  ELð  SUò  VWð  XYð  VYó  SZô  \^÷  \añ  \añ  Saó  SZÜˆƒFˆD‚L”|Ð&QÔRUÐVWÓRXÐQYÐ$ZÓ[Ð[Ü‡7�7Œ4Ð<Ñ<È%ÔP€ÔV]Ð^_Ð`kÑ^lÓVm×VsÑVsÐtuÐ~ÐVsó  WAÑQUÐQRÐSUð  GHð  IJð  K^ñ  I_ð  `bñ  Icñ  Gc÷  Fhñ  Fhð  ijó  Fkð  BEð  pqð  rsñ  psô  vx÷  v|ñ  v|ð  }@ó  vAð  BDñ  vDñ  oEô  FH÷  FQñ  FQð  RSð  T_ñ  R`ð  acñ  Rdó  Feñ  oeô  fh÷  fqñ  fqð  rsð  tñ  r@ð  ACñ  rDó  fEñ  oEð  lnô  MO÷  MUñ  MUð  VYð  [\ñ  V\ð  ]_ð  `có  Mdð  FLð  ghð  itñ  guð  vxñ  gyð  z@ñ  g@ð  efð  CDð  EPñ  CQð  RTñ  CUð  V\ñ  C\ð  ABô  `b÷  `jñ  `jð  klð  mnó  `oð  ]_ô  su÷  s}ñ  s}ð  ~ð  @Aó  sBð  prð  FHð  IKñ  FKð  MNñ  ENð  CDð  QSð  TVñ  QVð  OPô  Y[÷  Y`ñ  Y`ð  bdð  egñ  bgð  hjð  kmñ  hmñ  bmð  opñ  apó  Yqð  WXð  uvô  wy÷  w|ñ  w|ñ  u|ô  ~@÷  ~Hñ  ~Hð  IKð  LNñ  INð  OQð  RTñ  OTó  ~Uñ  tUð  rsô  \^÷  \añ  \að  bdð  egð  hið  jkð  lmð  noð  boñ  \p÷  \wñ  \wð  x|ó  \}ð  V[ð  IJð  ~Cð  EGð  DGñ  ~Hô  MO÷  MRñ  MRð  STð  UZð  SZñ  M[ð  KLô  ac÷  afñ  afð  gkô  ln÷  luñ  luð  vxò  yzð  {ð  yñ  v@	ð  A	B	ð  C	D	ó  lE	ð  gE	ñ  aF	ð  \`Ü‡��T 4€Ô(¬T°!«W¨°S·Z±ZÀ!Ç(Á(È4Ã.Ð_cÔrw×r~Ñr~ð  @Fó  sG°Zô  6Hô  IK÷  I\ñ  I\ô  ]bð  c|ñ  ]|ñ  ICð  Bò  ICô  DF÷  DWñ  DWô  X]ð  ^Fñ  XFð  ^`÷  ^gñ  ^gð  hló  ^mð  EG÷  ENñ  ENð  OSó  ETð  pq÷  pxñ  pxð  y}ó  p~ð  XY÷  X`ñ  X`ð  aeó  Xfð  @÷  Gñ  Gð  HLó  Mð  ^_÷  ^fñ  ^fð  gkó  ^lð  Að  VW÷  V^ñ  V^ð  _có  Vdð  ps÷  pzñ  pzð  {ó  p@	õ  DA	Ø#¸ÌcÐRSÐTZÑR[×RaÑRaÐbcÑRdÓNeð  v\ð  hIð  hmô  ^cð  df÷  dkñ  dkó  dmó  ^nô  }@ð  AC÷  AGñ  AGó  AIó  }Jô  [^ð  acð  `c÷  _hñ  _hó  _jó  [kð  yO
ð  [
xð  BHñ  IIñ  J€ô  LQð  Rwñ  Lw÷  KCñ  KCô  DH÷  DNñ  DNð  OSð  afð  noô  Dpð  z@ð  KCô  KAØ˜! !¬2¯5©5Ô1IÈ!ÌEÓ1RÐSW×S^ÑS^Ð_cÓSdÐ1dÑ+e×+lÑ+lÐmqÓ+rÐz~ð  GKð  QSð  [\ð  ]cñ  [d÷  [kñ  [kð  lpó  [qð  y}ñ  	~ð  ~ùò 1J×(Ñ(ús   ¡T°T½TÔTÔT%c                 ó|  — g } t        t        dz  j                  d«      «      D ]k  }t        j                  |d¬«      5 }| j                  t        |d   j                  «       «      |j                  D �ci c]  }|||   “Œ
 c}f«       d d d «       Œm t        | «      dk7  rt        d«      ‚| S c c}w # 1 sw Y   Œ—xY w)Nzdata_processed/pairedz*_cad_ply_targets.npzFr:   Úrun_idrM   z requires exactly two paired runs)Úsortedr   Úglobrr   rs   Úappendr/   Úitemrt   ry   rz   )Úoutr4   r”   r•   s       r5   Úpairsr±       s®   € Ø€Ü
”$Ð.Ñ.×4Ñ4Ð5LÓMÖ
N€QÜ	‡w�wˆq˜eÕ$¨¨#¯*©*´c¸!¸H¹+×:JÑ:JÓ:LÓ6MÐ_`×_fÒ_fÓNgÑ_fÐZ[ÈqÐQRÐSTÑQUÉvÐ_fÑNgÐ5hÔ*i×$Ð$ð OäˆƒHˆa‚K”lÐ#EÓFÐFØ€ùò Oh×$Ð$ús   ¾5B2Á3B-Â B2Â-B2Â2B;	c                óò  — | d   j                  d«      j                  «       }| d   j                  t        «      }t        | d   j                  t        «      «      \  }}|j                  «       }t        j                  t        |«      t        «      }d| d   | d   fd| d	   | d
   ffD ]Z  \  }}}t        dd«      D ]E  }	|› |	d›�}
|
|v sŒ||	dz
     sŒ||	dz
     ||j                  |
«      <   d||j                  |
«      <   ŒG Œ\ ||z  }t        j                  t        t        j                  ||d«      d    t        j                  |«      |«      d   |j                  d«      |j                  d«      f   |fS )NÚ	process_xr=   Úprocess_feature_validÚprocess_feature_namesu   ìƒ�ë¶€ì˜¨ë�„Úheater_top_cÚheater_top_imputedu   í•˜ë¶€ì˜¨ë�„Úheater_bottom_cÚheater_bottom_imputedrF   é   Ú02dr   )ru   rw   rv   r
   r/   Útolistrr   Úzerosry   ÚrangeÚindexÚr_r	   r   Úasarray)r?   rl   ÚobsÚnamesÚunitsÚimpÚpreÚvalÚflagr–   r•   Úgoods               r5   ÚprocrÊ   &   s  € Ø€{�^×Ñ˜4Ó ×%Ñ%Ó'€¨AÐ.EÑ,F×,MÑ,MÌdÓ,S¨Ô`tÐuvð  xOñ  vP÷  vWñ  vWô  X[ó  v\ó  a]ÑT_ÐTYÐZ_ð  di÷  dpñ  dpó  drð  ^cô  wy÷  wñ  wô  @Cð  DGó  @Hô  IMó  wNð  svØ% a¨Ñ&7¸Ð:NÑ8OÐPÐR`ÐabÐctÑauÐvwð  yPñ  wQð  RRó  S�\€SˆˆTÜ��2Ž;€aØ€uˆQˆsˆG€_€1Øˆ5‚j�T˜!˜A™#“Y°3°q¸±s±8˜s 5§;¡;¨q£>Ñ2ÐPQ¸CÀÇÁÈAÃÒ<Oñ ð Sð 
ˆ#�g€”R—U‘UÔ3´B·H±H¸TÀ#ÀaÓ4HÈÑ4NÌrÏzÉzÐZ_ÓO`ÐafÓgÐhiÑjÐkn×kuÑkuÐvzÓk{Ð|÷  }Gñ  }Gð  HLó  }Mð  Mñ  Nð  OTð  Tð  Tr7   c                óœ  — g }g }g }|D ]½  \  }}t        |d   «      j                  | d   d¬«      \  }}|j                  |j                  d«      «       |j                  |d   |df   j                  d«      «       |j                  t	        j
                  |d   |   t         t        «      j                  d«      t        z  «       Œ¿ |||fS )NÚ
cad_pos_mmrk   rF   rG   r=   Úweak_defect_probabilityÚcad_to_scan_normal_residual_mm)r   r{   r®   ru   rr   ÚclipÚSCALE)	ÚgÚrowsÚrr›   ÚdistÚ_r?   ÚqÚis	            r5   ÚlabelsrØ   -   s<  € Ø€ˆ€a�ˆ4Û�S€Q€qÜˆa�‰oÓ×$Ñ$ Q u¡X°aÐ$Ó8�#€!€A¸¿¹ÀQÇXÁXÈdÃ^Ô9TÐUV×U]ÑU]Ð^_Ð`yÑ^zÐ{|Ð}~Ð{~Ñ^÷  _Gñ  _Gð  HLó  _Mô  VNð  OP÷  OWñ  OWô  XZ÷  X_ñ  X_ð  `að  bBñ  `Cð  DEñ  `Fô  HMð  GMô  NSó  XT÷  X[ñ  X[ð  \`ó  Xaô  bgñ  Xgõ  Ohð à	ˆ!ˆDˆ€r7   c                  ó&   ‡ — e Zd Zdˆ fd„	Zd„ Zˆ xZS )ÚNetc           	     ó`  •— t         ‰| �  «        t        j                  t        j                  ||«      t        j
                  «       t        j                  ||«      t        j
                  «       «      | _        t        j                  t        j                  ||«      t        j
                  «       t        j                  ||«      «      | _        t        j                  t        j                  ||«      t        j
                  «       t        j                  ||«      «      | _        t        j                  t        j                  d|z  |«      t        j
                  «       t        j                  ||«      t        j
                  «       «      | _	        t        j                  t        d«      D �cg c]  }t        j                  d|z  |«      ‘Œ c}«      | _        t        j                  |d«      | _        t        j                  |d«      | _        t        j                  |d«      | _        y c c}w )Né   rM   rF   )ÚsuperÚ__init__r   Ú
SequentialÚLinearÚGELUrm   rn   ÚprocessÚmsgÚ
ModuleListr¾   ÚGRUCellÚupÚriskÚsignedÚmag)Úselfr”   r    rš   ÚwrÕ   Ú	__class__s         €r5   rÞ   zNet.__init__3   ss  ø€ Ü�'ÑÔœrŸ}™}¬R¯Y©Y°q¸«^¼B¿G¹G»IÄbÇiÁiÐPQÐRSÃnÔUW×U\ÑU\ÓU^Ó_�T”YÔjl×jwÑjwÔxz÷  yBñ  yBð  CDð  EFó  yGô  HJ÷  HOñ  HOó  HQô  RT÷  R[ñ  R[ð  \]ð  ^_ó  R`ó  kaÐ`dÔ`iô  oq÷  o|ñ  o|ô  }÷  }Fñ  }Fð  GHð  IJó  }Kô  LN÷  LSñ  LSó  LUô  VX÷  V_ñ  V_ð  `að  bcó  Vdó  oeð  bfô  bnô  oq÷  o|ñ  o|ô  }÷  }Fñ  }Fð  GHð  IJñ  GJð  KLó  }Mô  NP÷  NUñ  NUó  NWô  XZ÷  Xañ  Xað  bcð  deó  Xfô  gi÷  gnñ  gnó  gpó  oqð  fjô  fnô  z|÷  zGñ  zGô  dið  jkô  dló  Hmñ  dlð  _`ô  IK÷  ISñ  ISð  TUð  VWñ  TWð  XYõ  IZð  dlñ  Hmó  znð  rvô  ryô  y{÷  yBñ  yBð  CDð  EFó  yGð  osô  oxô  TV÷  T]ñ  T]ð  ^_ð  `aó  Tbð  HLô  HSô  ln÷  luñ  luð  vwð  xyó  lzð  cgõ  ckùò  Hms   Æ- H+c           
     ó   — | j                  |«      }| j                  |«      |   }|\  }}	| j                  |«      }
| j                  D ]  }| j	                  t        j                  ||   ||	   ||   z
  |
||   fd«      «      }t        j                  |«      j                  d|	|«      } |t        j                  ||fd«      |«      }Œ� | j                  |«      j                  d«      }| j                  |«      j                  d«      ||j                  «       t        j                  | j                  |«      j                  d«      «      z   dœS )NrF   r   )rç   rè   ré   )rm   râ   rn   ræ   rã   ÚtorchÚcatÚ
zeros_likeÚ
index_add_rè   Úsqueezerç   r}   ÚFÚsoftplusré   )rê   r?   Úerp   r4   r    ÚhrÖ   ÚsÚtr–   ÚuÚmr”   r›   s                  r5   ÚforwardzNet.forward5   sC  € Ø‡I�IˆaƒL€!�4—<‘< “? 1Ñ%�¨!¡c a¨¨d¯i©i¸«m¨AØ�7Œ7€a�T—X‘XœeŸi™i¨¨1©¨a°©d°1°Q±4©i¸¸!¸A¹$Ð(?ÀÓBÓC�1Äe×FVÑFVÐWXÓFY×FdÑFdÐefÐghÐijÓFkÀAÑnoÔpu×pyÑpyÐ{|Ð}~Ðzð  ABó  qCð  DEó  oFÑlmˆ7Ø‡K�K�ƒN×Ñ˜1Ó€!¨T¯Y©Y°q«\×-AÑ-AÀ!Ó-DÈaÐVW×V[ÑV[ÓV]Ô^_×^hÑ^hÐim×iqÑiqÐrsÓit×i|Ñi|Ð}~Óió  _Añ  WAñ  &Bð  Br7   )é0   )Ú__name__Ú
__module__Ú__qualname__rÞ   rû   Ú__classcell__)rì   s   @r5   rÚ   rÚ   2   s   ø„ õzöBr7   rÚ   c                ó¶  — | dk\  }|dk\  }t        ||z  j                  «       «      }t        ||z  j                  «       «      }t        j                  |  d¬«      }||   j	                  t
        «      }t        t        j                  |«      t        j                  dt        |«      dz   «      z  |z  j                  «       t        d|j                  «       «      z  «      }||t        d|«      z  d|z  t        dt        |j                  «       |j                  «       z   «      «      z  t        |j                  «       «      t        |j                  «       «      dœS )Ng      à?Ústable)ÚkindrF   rM   )ÚAPú
IoU_at_0.5zDice_at_0.5Útarget_nodesÚpredicted_nodes)
rŒ   r|   rr   Úargsortru   rŽ   ÚcumsumÚarangery   Úmax)	r4   Úyr–   rø   r×   rù   Úor”   Úaps	            r5   Úmetricr  9   s?  € Ø€b�5€ˆ1ˆb‰5ˆ”3˜˜!™—y‘y“{Ó#�¤c¨1¨Q©3¯)©)«+Ó&6 A¼¿¹ÀQÀBÈHÔ9U°qÐXYÐZ[ÑX\×XcÑXcÔdiÓXjÐVWÔnsÔuw×u~Ñu~ð  @Aó  vBô  CE÷  CLñ  CLð  MNô  ORð  STó  OUð  VWñ  OWó  CXñ  vXð  YZñ  vZ÷  u_ñ  u_ó  uaô  beð  fgð  hi÷  hmñ  hmó  hoó  bpñ  upó  oqÐkmð  Að  OPô  QTð  UVð  WXó  QYñ  OYð  hið  jkñ  hkô  loð  pqô  ruð  vw÷  v{ñ  v{ó  v}ð  ~÷  ~Cñ  ~Có  ~Eñ  vEó  rFó  lGñ  hGô  WZð  [\÷  [`ñ  [`ó  [bó  Wcô  vyð  z{÷  zñ  zó  zAó  vBñ  yCð  rCr7   c                ó¬  — |dk(  r!t        t        t        t        «      «      «      ng d¢}|dk(  rt        t        d«      «      ng d¢}t        j
                  | d   d d …|f   | d   d d …t	        j                  |«      t        t        «      z   f   f   | d   d d …|f   |D �cg c]  }t        |   ‘Œ c}|D �cg c]  }t        |   ‘Œ c}fS c c}w c c}w )NÚdihedral_aware)	r   rF   rM   rJ   rÜ   rD   rN   é   é   é   )r   rF   rM   rJ   rÜ   rm   rp   )Úlistr¾   ry   rŠ   rr   r„   rÁ   ÚENAMES)rÑ   r  ÚniÚeir×   s        r5   Úselectr  ;   sï   € à#Ð%5Ò5„DŒŒs”5‹zÓ	ÔÒ;O€ÐeiÐk{Òe{ÔSWÔX]Ð^_ÓX`ÔSaò  BMÐPRÜ
�‰ˆa�‰iš˜"˜‰o˜a ™iª¬"¯*©*°R«.¼¼U»Ñ*CÐ(CÑDÐDÑEÀaÈÁgÊaÐPRÈdÁmÑgiÓTjÑgiÐbcÔUZÐ[\ÓU]ÐgiÑTjñ  @Bó  lCñ  @BÐz{ÔlrÐstÓluð  @Bñ  lCð  	Cð  CùÒTjùò  lCs   Â"CÂ8C
c                óH  — t        «        t        | |«      \  }}}}t        | |«      \  }	}
}t        d„ |D «       Ž \  }}t	        | d   «      }t
        j                  ||f   }t
        j                  | d   | d   |z   f   }t
        j                  ||f   }t        j                  t        j                  d«      |«      }t
        j                  |	d   |	d   f   }t
        j                  |
d   |
d   f   }t        |j                  d   |j                  d   t	        |d   «      «      }t        j                  j                  |j                  «       |d¬«      }t!        t        j"                  |||t        j$                  |d	«      |f«      \  }}}}}|j'                  «       }|j'                  «       }t        j"                  |«      }t        j"                  |«      }t	        |«      |j)                  «       z
  |j)                  «       j+                  d«      z  j-                  d
¬«      }g }d} t/        |«      D �]  }!|j1                  «         ||||||«      }"t3        j4                  |"d   ||¬«      }#ddt        j6                  |"d   «      |z  j)                  «       z  dz   t        j6                  |"d   «      j)                  «       |j)                  «       z   dz   z  z
  }$t3        j8                  |"d   |d¬«      }%t3        j8                  |"d   |j;                  «       d¬«      }&|#|$z   d|%z  z   d|&z  z   }'|'j=                  «        |j?                  «        |!dz   tA        |'jC                  «       «      tA        |#jC                  «       «      tA        |$jC                  «       «      tA        |%jC                  «       «      tA        |&jC                  «       «      dœ}(|jE                  |(«       |(d   | d   k  s�Œº|(d   |!dz   |jG                  «       jI                  «       D �)�*ci c]$  \  })}*|)|*jC                  «       jK                  «       “Œ& c}*})f} �Œ |jM                  | d   «       |jO                  «        t        jP                  «       5   ||||||«      }"t        j6                  |"d   «      jS                  «       }+|"d   jS                  «       tT        z  },|"d   jS                  «       tT        z  }-d d d «       tW        |«      D �.�/�cg c]`  \  }.\  }/}|/+|.|z  |.dz   |z   ,|.|z  |.dz   |z   -|.|z  |.dz   |z   |	|.   |
|.   tT        z  ||.   tY        |+|.|z  |.dz   |z   |	|.   «      dœ‘Œb }0}/}.}||t[        |«      t[        |«      || d   | d   |0dœfS c c}*})w # 1 sw Y   Œ«xY wc c}}/}.w )Nc              3  ó8   K  — | ]  \  }}t        |«      –— Œ y ­w)N)rÊ   )Ú.0rÕ   r?   s      r5   Ú	<genexpr>ztrain.<locals>.<genexpr>@   s!   è ø€ Ð`yÑtxÑmpÐmnÐopÔaeÐfg×ahÑtxùs   ‚rk   rn   rM   r   rF   gñhãˆµøä>)ÚlrÚweight_decayr=   éÈ   )r  )g    eÍÍAr   Nrç   )Ú
pos_weightrè   g333333Ã?)Údeltaré   çš™™™™™É?)ÚepochÚtotalÚrisk_bceÚ	risk_diceÚsigned_deformation_huberÚmagnitude_deformation_huberr%  )Úrunrç   rè   ré   ÚweakÚtarget_signedÚmap_distance_mmr  )ÚvariantÚnode_featuresÚedge_featuresÚhistoryÚ	best_lossÚ
best_epochÚruns).r   r  rØ   Úzipry   rr   rÀ   r„   r…   r
  rÚ   r�   rî   ÚoptimÚAdamWÚ
parametersÚmapÚ	as_tensorrÁ   Úlongr|   Ú	clamp_minÚclampr¾   Ú	zero_gradró   Ú binary_cross_entropy_with_logitsÚsigmoidÚ
huber_lossr}   ÚbackwardÚsteprŽ   Údetachr®   Ú
state_dictÚitemsÚcloneÚload_state_dictÚevalÚno_gradÚnumpyrÐ   Ú	enumerater  r  )1rÑ   rÒ   r  Úepochsr  Úx0Úe0ÚnnamesÚenamesrç   ÚdeformrÔ   ÚpvrÕ   r˜   r?   rõ   rp   r    ÚtrÚtdr   ÚoptÚXÚEÚAÚPÚBÚRÚDÚpwÚhistÚbestÚepr  ÚbceÚdiceÚdlÚmlÚlossrö   r•   r—   r4   r÷   rú   Újr*  r4  s1                                                    r5   Útrainrh  ?   sô
  € ÜÔ¤v¨a°£~Ñ&�2�b˜ ÄvÈaÐPTÃ~Ñ6F°d¸6À$Ô[^Ñ`yÑtxÓ`yÐ[zÑVZÐVXÐYZô  ~Að  BCð  DIñ  BJó  ~KÐ{|ô  NP÷  NSñ  NSð  TVð  WYð  TYñ  NZð  LMô  ]_÷  ]bñ  ]bð  cdð  ekñ  clð  mnð  ouñ  mvð  wxñ  mxð  cxñ  ]yð  [\ô  }÷  }Bñ  }Bð  CEð  FHð  CHñ  }Ið  z|ô  LN÷  LUñ  LUô  VX÷  V_ñ  V_ð  `aó  Vbð  cdó  Leð  JKô  ik÷  inñ  inð  osð  tuñ  ovð  w{ð  |}ñ  w~ð  o~ñ  ið  fhô  CE÷  CHñ  CHð  IOð  PQñ  IRð  SYð  Z[ñ  S\ð  I\ñ  C]ð  @Bô  dgð  hi÷  hoñ  hoð  pqñ  hrð  su÷  s{ñ  s{ð  |}ñ  s~ô  Bð  CEð  FGñ  CHó  Ió  dJð  ^cô  OT÷  OZñ  OZ÷  O`ñ  O`ð  af÷  aqñ  aqó  asð  wyð  GKð  O`ó  OLð  KNô  WZô  [`÷  [jñ  [jð  lmð  noð  prô  su÷  s}ñ  s}ð  ~@ð  AEó  sFð  GHð  kIó  WJñ  MVð  MNð  OPð  QRð  STð  UVð  MN÷  MSñ  MSó  MUð  KLð  XY÷  X^ñ  X^ó  X`ð  VWô  ch÷  crñ  crð  suó  cvð  abô  y~÷  yHñ  yHð  IKó  yLð  wxô  RUð  VWó  RXð  YZ÷  Y^ñ  Y^ó  Y`ñ  R`ð  bc÷  bgñ  bgó  bi÷  bsñ  bsð  tuó  bvñ  Qv÷  P}ñ  P}ð  B	E	ð  P}ó  PF	ð  MOð  L	N	ð  G	K	ð  T	`	ð  O	S	Ü��=€RØ‡-�-„/‘E˜!˜A˜a  !Ó$�!¬×)KÑ)KÈAÈfÉIÐVWÐceÔ)f SÐlmÐopÔrw×rÑrð  ABð  CIñ  AJó  sKð  LMñ  sM÷  rRñ  rRó  rTñ  pTð  UVñ  pVô  Y^÷  Yfñ  Yfð  ghð  ioñ  gpó  Yq÷  Yuñ  Yuó  Ywð  xy÷  x}ñ  x}ó  xñ  Yð  @Añ  YAñ  oBñ  mBÐgkô  FG÷  FRñ  FRð  STð  U]ñ  S^ð  _`ð  gjô  Fkð  CEô  op÷  o{ñ  o{ð  |}ð  ~Cñ  |Dð  EF÷  EJñ  EJó  ELð  SVô  oWð  lnð  ]`ð  aeñ  ]eð  fhð  ikñ  fkñ  ]kð  lnð  oqñ  lqñ  ]qð  X\ð  rv÷  rñ  rô  rAð  BE÷  BJñ  BJô  BLð  XZð  [\ñ  X\ô  ejð  ko÷  kvñ  kvó  kxó  eyô  EJð  KN÷  KUñ  KUó  KWó  EXô  ejð  ko÷  kvñ  kvó  kxó  eyô  UZð  []÷  [dñ  [dó  [fó  Ugô  FKð  LN÷  LUñ  LUó  LWó  FXñ  OYð  MNð  Z^÷  Zeñ  Zeð  fgô  ZhØ€w�Z��Q‘Ô˜a ™j¨¨A©Èu×O_ÑO_ÓOa×OgÑOgÔOiÔ.jÑOiÉÈÈ!¨q°·±³×1AÑ1AÓ1CÑ/CÐOiÒ.jÐkšð ð ×Ñ�t˜A‘wÔ §
¡
¤Ü‡m�m…o™˜a  ! A aÓ(�a¬5¯=©=¸¸6¹Ó+C×+IÑ+IÓ+K¨ÈaÐPXÉk×N_ÑN_ÓNaÔbgÑNgÈAÐjkÐlqÑjr×jxÑjxÓjzô  |Añ  kAÐhi‡oô Ybð  cgô  Yhõ  iñ  Yhñ  LUð  LMñ  NUð  ORð  STˆc˜˜1˜Q™3  !¡ Q™w˜°°1°Q±3¸¸!¹¸Q±w°ÀaÈÈ!ÉÈQÈqÉSÐRSÉGÀnÐ\`ÐabÑ\cÐtzÐ{|Ñt}ô  Dñ  uDð  W[ð  \]ñ  W^ô  hnð  opð  qrð  stñ  qtð  vwð  xyñ  vyð  {|ñ  u|ð  o}ð  ~Bð  CDñ  ~Eó  hFó  Gð  Yh€ò  iØ˜¬d°6«lÌ4ÐPVË<ÐbfÐswÐxyÑszð  IMð  NOñ  IPð  X\ñ  ]ð  	]ð  ]ùó	 /kç€oüô is   Ð)VÒ A'VÓ>A%VÖVc                óæ  — t        | d   «      }t        j                  d| d   j                  d   dz
  t	        d| d   j                  d   «      t
        ¬«      }t        j                  |«      }t        j                  |«      }t        j                  j                  || d   d   | d   d d …df   «       t        j                  j                  || d   d   d«       t        j                  |d	d
«      }t        | d   d   «      D ]  \  }}	||	   dk  sŒ|||	<   Œ | d   d d …|f   j                  j                  «       }
| d   j                  }i }t        |«      D ]q  \  }}|d   |d   f|d   |d   f|d   |d   ffD ]L  \  }	}|j                  t        t        t        |	«      t        |«      f«      «      g «      j!                  |«       ŒN Œs | d   |   }t        j"                  |d d …df   |d d …df   z
  |d d …df   |d d …df   z
  «      }|t        j$                  t        j&                  j)                  |dd¬«      d«      z  }g }|
D ]ÿ  \  }	}|j+                  t        t        |	|f«      «      g «      }t        |«      dk(  r—|j!                  d||   j-                  d«      j                  «       ||   j-                  d«      j                  «       t/        t        j0                  t        j2                  ||d      ||d      z  d	d«      «      «      dœ«       ŒÑ|j!                  t        |«      dk(  rdndt        |«      ddœ«       �Œ g }|D �]ô  }g }t5        |d   |«      D �]¶  \  }\  }}t7        |d   j9                  t:        «      «      d   j                  «       }g }dD ]P  }|j=                  |«      }|j!                  ||d   |   rt/        |d   |   «      nd t?        |d   |   «      dœ«       ŒR |j!                  i |jA                  «       D ��ci c]F  \  }}|dv sŒ|tC        |t        jD                  «      r|j-                  d«      j                  «       n|“ŒH c}}¥|d   j-                  d«      j                  «       |d    j-                  d«      j                  «       |d!   j-                  d«      j                  «       |d"   j9                  t>        «      j                  «       |d#   j9                  t>        «      j                  «       |d$œ¥«       �Œ¹ |j!                  |d%   |d%   d&k(  rd'nd(|d)   |d*œ«       �Œ÷ | d+   }| d,   d d …t        tF        «      d-z   f   j9                  t>        «      }||d d …d.f   d/kD  z  } t        jH                  | dt        jH                  |d d …d0f   dk  dt        jH                  |  dt        jH                  |d d …d-f   dk\  d1d«      «      «      «      }!| d   j-                  d«      j                  «       | d2   j-                  d«      j                  «       | d   d d …|f   j                  j                  «       |d d …d3f   j-                  d«      j                  «       |d d …d4f   j-                  d«      j                  «       |d d …d5f   j-                  d«      j                  «       |d d …d-f   j-                  d«      j                  «       |d d …d6f   j-                  d«      j                  «       |j                  «       | j                  «       |!j                  «       |t        j$                  |d«      z  j-                  d«      j                  «       d7œ	|
t        tJ        «      D �"�ci c]6  \  }"}t;        |«      | d   ||"f   j-                  d«      j                  «       “Œ8 c}}"||d8| d   j                  d   › d9�g d:¢d;œ
S c c}}w c c}}"w )<Nrk   r   rn   rF   i”  )Údtypero   rD   éÿÿÿÿrj   rV   rM   T)ÚaxisÚkeepdimsg:Œ0âŽyE>Útwo_facerÜ   rN   )ÚstatusÚ	trianglesÚnormalsÚ	theta_radÚboundaryÚnonmanifold_or_missingz*face dihedral undefined; no theta invented)ro  Ú
face_countÚpolicyr4  rµ   )u   ê°€ì—´ì‹œê°„u   ê°€ì—´ì˜¨ë�„u   ìƒ�ë¶€ì›�ë‹¨ì˜¨ë�„u   í•˜ë¶€ì›�ë‹¨ì˜¨ë�„r´   r³   )ÚnameÚvalueÚobserved)r*  rç   rè   ré   r+  r  ré   r¶   r¸   r·   r¹   )Ú	magnituder¶   r¸   r·   r¹   Úkey_global_processr.  r  zDihedral-aware GNNzNormal GNN baseliner2  )ÚidÚlabelr2  r4  rl   rm   rº   é   g�íµ ÷Æ°>é   rJ   r>   r  é   é
   é   )	r   r   r   r"   r%   Úcad_signed_curvature_validÚcad_shape_index_validÚcad_shape_classÚmean_adjacent_dihedral_radz	4,500 of zA directed edges drawn; selected edge and all-edge mean are exact.)zRPrepared graph_6000: requested ~6k, actual 5,925 nodes; no padding or duplication.zïSigned CAD curvature is gray/unknown outside the orientation-valid mask; shape index is additionally undefined at near-zero curvedness. H positive/negative follows prepared-normal convention, not universal outward convexity; K<0 is saddle.zLTwo NG scans and point-dilated weak labels only; no held-out generalization.zeNo validated registration, local thermal field, material/contact/FLC, stress/strain, or tear physics.)
Únodesrq  ÚedgesÚnode_featureÚincident_edgesÚincident_edge_featureÚincident_face_geometryÚmodelsÚedge_draw_noteÚlimitations)&ry   rr   Úlinspacer�   ÚminrŒ   r½   ÚaddÚatÚfullrL  ÚTr¼   Ú
setdefaultÚtupler¬   r®   Úcrossr€   ÚlinalgÚnormÚgetÚroundrŽ   ÚarccosrÏ   r5  r
   ru   r/   r¿   rv   rF  Ú
isinstanceÚndarrayrŠ   r   r  )#rÑ   ÚinfosrÒ   r˜   Úpickr%  ÚdegreeÚfirstrg  r”   ÚincÚfacesÚfmÚfirø   r    ÚtriÚfnÚfgÚfsr�  ÚinfoÚrsrÓ   rÕ   r?   rÃ   Úkeysr•   r—   rl   ÚvalidÚ
shapevalidÚshape_classr×   s#                                      r5   Úviewr²  H   s9  € Ü€qˆ�xƒ=€”b—k‘k ! A f¡I§O¡O°AÑ$6°qÑ$8¼¸TÀ!ÀFÁ)Ç/Á/ÐRSÑBTÓ9UÔ\_Ô`�Ôgi×goÑgoÐpqÓgrÐafÔz|÷  {Cñ  {Cð  DEó  {FÐsyô  GI÷  GMñ  GM÷  GPñ  GPð  QVð  WXð  Y_ñ  W`ð  abñ  Wcð  deð  flñ  dmò  noð  pqð  nqñ  drô  Gsô  tv÷  tzñ  tz÷  t}ñ  t}ð  ~Dð  EFð  GMñ  ENð  OPñ  EQð  RSô  tTô  []÷  [bñ  [bð  cdð  egð  hló  [mð  UZÜ�a˜‘i ‘lÖ#�S€Q€qØ
ˆ1�XˆaƒZ˜��a’ð $à€v�YŠq�ˆwÑ×Ñ× Ñ Ó"€¨¨6©¯© 5¸°RÜ�uÖ�T€RˆØ�‰t�A�a‘Dˆk˜1˜Q™4  !¡˜+ q¨¡t¨A¨a©D kÓ2�c€aˆ°2·=±=ÄÄvÌsÐSTËvÔVYÐZ[ÓV\ÈoÓG^ÓA_Ð`bÓ3c×3jÑ3jÐkmÕ3nÑ2ð à€u�Xˆe�_€œŸ™ ¢Q q S¡¨#ªa°¨c©(Ñ!2°3²q¸°s±8¸CÂÀ!À¹HÑ3DÓE�RÀbÌ"Ï*É*ÔUW×U^ÑU^×UcÑUcÐdfÐlmÐw{ÐUcÓU|ð  ~Bó  KCñ  GCÀbð  GIð  DFÛ�S€Q€qØ‡V�VŒE”&˜!˜A˜“-Ó  Ó$€"ÜˆƒWˆa‚Z�—	‘	 J¸3¸r¹7¿=¹=ÈÓ;K×;RÑ;RÓ;TÐ_aÐbdÑ_e×_kÑ_kÐlmÓ_n×_uÑ_uÓ_wô  EJô  KM÷  KTñ  KTô  UW÷  U\ñ  U\ð  ]_ð  `bð  cdñ  `eñ  ]fð  gið  jlð  mnñ  joñ  gpñ  ]pð  qsð  tuó  Uvó  Kwó  Exñ  yõ  zØ	‡y�y¬¨R«°!ª™:Ð9QÔ_bÐceÓ_fð  q]ñ  ^ö  _ð ð 	€Ü€TØ€"Ü�T˜&‘\ $×'�g€a‰ˆˆ1Ü	˜aÐ 7Ñ8×?Ñ?ÄÓDÓ	EÀaÑ	H×	OÑ	OÓ	Q€5ÐWYÐRVÛU€qØ‡k�k�!ƒn€A�T—[‘[¨ÈqÐQhÑOiÐjkÒOl´5¸¸;¹ÈÑ9JÔ3KÐrvô  CGð  HIð  Jañ  Hbð  cdñ  Heó  Cfñ  "gõ  hð Và‡9�9ð  RÐWX×W^ÑW^ÔW`ô  XÑW`ÑPSÐPQÐRSÐdeð  jWò  eW�¬:°a¼¿
¹
Ô+C�A—G‘G˜A“J×%Ñ%Ô'ÈÑJÐW`ò  Xð  Rð  efð  glñ  em÷  esñ  esð  tuó  ev÷  e}ñ  e}ó  eð  OPð  Q_ñ  O`÷  Ofñ  Ofð  ghó  Oi÷  Opñ  Opó  Orð  EFð  GXñ  EY÷  E_ñ  E_ð  `aó  Eb÷  Eiñ  Eió  Ekð  ABð  CWñ  AX÷  A_ñ  A_ô  `dó  Ae÷  Alñ  Aló  Anð  GHð  I`ñ  Ga÷  Ghñ  Ghô  imó  Gn÷  Guñ  Guó  Gwð  MQò  Rö  Sð	 (ð
 	‡-�-�d˜9‘oÀdÈ9ÁoÐWgÒFgÑ.Bð  nCð  PTð  U`ñ  Pað  ikñ  lö  mð ð €u�X€�A�f‘Iša¤¤E£
¨2¡˜oÑ.×5Ñ5´dÓ;ˆeÀuÈcÒRSÐTVÐRVÉiÐX\ÉnÑG]¸JÔjl×jrÑjrÐtyÐsyÐz{Ô|~÷  }Eñ  }Eð  FIò  JKð  LNð  JNñ  FOð  PQñ  FQð  RSô  TV÷  T\ñ  T\ð  ^hð  ]hð  ijô  km÷  ksñ  ksð  twò  xyð  z|ð  x|ñ  t}ð  @ñ  t@ð  ABð  CDó  kEó  TFó  }Gó  kHÐ^ið  YZð  [`ñ  Ya÷  Ygñ  Ygð  hió  Yj÷  Yqñ  Yqó  Ysð  ~ð  @Hñ  ~I÷  ~Oñ  ~Oð  PQó  ~R÷  ~Yñ  ~Yó  ~[ð  deð  flñ  dmò  noð  ptð  ntñ  du÷  dwñ  dw÷  d~ñ  d~ó  d@ð  orò  stð  uvð  svñ  ow÷  o}ñ  o}ð  ~ó  o@÷  oGñ  oGó  oIð  Y\ò  ]^ð  _að  ]añ  Yb÷  Yhñ  Yhð  ijó  Yk÷  Yrñ  Yró  Ytð  EHò  IJð  KMð  IMñ  EN÷  ETñ  ETð  UVó  EW÷  E^ñ  E^ó  E`ð  ~Aò  BCð  DFð  BFñ  ~G÷  ~Mñ  ~Mð  NOó  ~P÷  ~Wñ  ~Wó  ~Yð  loò  pqð  rtð  ptñ  lu÷  l{ñ  l{ð  |}ó  l~÷  lE	ñ  lE	ó  lG	ð  e	j	÷  e	q	ñ  e	q	ó  e	s	ð  L
V
÷  L
]
ñ  L
]
ó  L
_
ð  r
}
÷  r
Dñ  r
Dó  r
Fð  ejô  km÷  kuñ  kuð  v|ð  }~ó  kñ  e÷  dFñ  dFð  GHó  dI÷  dPñ  dPó  dRñ  PSð  ehô  yBô  CIô  yJô  AKñ  yJñ  ruð  rsð  tuô  BEð  FGó  BHð  IJð  KQñ  IRð  SXð  YZð  SZñ  I[÷  Iañ  Iað  bcó  Id÷  Ikñ  Ikó  Imñ  Bmð  yJò  AKð  egð  qwð  KTð  UVð  W]ñ  U^÷  Udñ  Udð  efñ  Ugð  Thð  hið  Ijò  yxñ  Pyð  Iyùó Xùó AKs   Ð_'Ð$>_'Þ;_-c                ó,  — | j                   st        d«      ‚t        «        t        «       }t	        «       }g }dD ]—  }t        |||| j                  | j                  «      \  }}t        j                  dd¬«       t        j                  |j                  «       |t        |d   «      |d   |d   dd	œt        |› d
�z  «       |j                  |«       Œ™ t        j                  dd¬«       |D �ci c]  }|d   |“Œ
 }}t!        j"                  t        dz  |d   |d   t!        j$                  t        |d   «      «      t!        j&                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j(                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j(                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j(                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j(                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j(                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j(                  |d   d   D �cg c]  }|d   ‘Œ	 c}«      t!        j*                  d«      ¬«       t        dz  t        dz  t        dz  t        dz  t,        dz  t,        dz  t,        dz  fD ]#  }	|	j/                  «       sŒ|	j1                  «        Œ% ddt        |d   «      t3        |d    j4                  d!   «      d"dd#d$d%|D �ci c]  }|d   |d   |d   d&œ“Œ c}d'œ
}
t,        d(z  j7                  t9        j:                  |
dd)¬*«      d+¬,«       t        d-z  j7                  t9        j:                  t=        |||«      dd.¬/«      d+¬,«       t?        j@                  d0¬1«      \  }}|D ��cg c]A  }|jC                  |d2   D �cg c]  }|d3   ‘Œ	 c}|d2   D �cg c]  }|d4   ‘Œ	 c}|d   ¬5«      ‘ŒC c}} |jE                  d6«       |jG                  «        |jI                  d7¬8«       |jK                  d9«       |jM                  t        d:z  d;¬<«       t?        jN                  |«       t?        j@                  d)d)d=¬1«      \  }}tQ        |«      D ]Ÿ  \  }}tQ        |d   «      D ]‰  \  }}|||f   jS                  |d   d d …df   |d   d d …d)f   |d   d)d>dd!¬?«      }|||f   jK                  |d   › d@|d   › dA�«       |||f   jU                  dB«       |jW                  ||||f   ¬C«       Œ‹ Œ¡ |jM                  t        dDz  d;¬<«       t?        jN                  |«       tY        |d   d   |d   d   «      D � �cg c]4  \  } }| d   | dE   |dE   |dE   dF   | dE   dF   kD  |dE   dG   | dE   dG   kD  dHœ‘Œ6 }} }dIdJdKdLdMdNdOdPœ}dQddR||D ��cg c]+  }|d   |dS   |dT   dU|d2   |d   D �cg c]  }|dE   ‘Œ	 c}dVœ‘Œ- c}}|
|
dW   |dXgdYœ	}t        dZz  j7                  t9        j:                  |dd)¬*«      d+¬,«       |S c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}w c c}}w c c}} w c c}w c c}}w )[NzBPass --allow-diagnostic-weak-labels: targets are weak/unvalidated.)Únormal_baseliner  TrO   rk   r/  r0  F)rE  r.  Ú
node_countr/  r0  Úproduction_validz_gnn.ptr.  z*prepared_graph_5925_direct_predictions.npzr>   r   r4  r*  r´  rç   r  rè   ré   )rÌ   Ú
cad_normalrµ  r«   Ú normal_baseline_risk_probabilityÚdihedral_risk_probabilityÚnormal_baseline_signed_mmÚdihedral_signed_mmÚnormal_baseline_magnitude_mmÚdihedral_magnitude_mmÚdirect_model_evaluationz#direct_original_cad_predictions.npzz!fixed_6000_direct_predictions.npzzdirect_original_predictions.pngztraining.pngz#finest_prepared_cad_graph_11956.npzzfixed_6000_surface_graph.npzz"fixed_6000_surface_provenance.jsonr9   rU   rV   rF   z0same prepared graph_6000 with 5,925 actual nodeszusame GNN/seed/epochs/loss/process/threshold; excludes curvature, analytic curvature, boundary/ridge and face dihedralzTacos(clamp(dot(two adjacent face normals), -1,1)); undefined on boundary/nonmanifoldaœ  A new CAD can execute with variable node count/topology, but this experiment fixes the ~6k preparation rule: independently simplify each new CAD with the same rule; node indices never correspond across designs; output is direct per-new-CAD-node. Generalization is unmeasured with one CAD/two runs. Use multi-design training, CAD-family held-out splits and OOD uncertainty before interpreting cross-design output.)rm   rn   )
Úsurface_graphr]   r^   r_   Ú!training_inference_viewer_outputsÚnode_density_is_risk_featurer´  Údihedral_face_definitionÚchanged_cadÚfeatureszfeature_contract.jsonrM   rd   rg   rh   zviewer_data.json)Ú,Ú:)re   Ú
separators)r  g      @)Úfigsizer1  r$  r%  )r}  Úlogr#  )Úalphaz<Same prepared graph_6000 (5,925 actual nodes) weak-label fitzloss_comparison.pngé    )Údpi)r�  r  Úmagma)rš   r÷   ÚcmapÚvminÚvmaxÚ z riskÚequal)Úaxzfixed_6000_model_overlays.pngr  r  r  )r*  r´  r  Údihedral_better_APÚdihedral_better_IoUÚ!conceptual_next_model_not_trainedz�CAD graph geometry encoder (curvature/face-dihedral/ridge/boundary) + XLS thermal/process encoder; local thermal projection only when heater footprints existz&segmentation/risk/deformation/thinningu"   defect type and physical area mmÂ²z”thermal risk and geometry risk cannot be separated from one fused label without branch-specific targets, controlled variation or concept supervisionuW   one CAD, two NG runs, only ì°�íž˜, no observed area; weak dilation is not physical areauœ   local temperature, thickness/material/FLC/contact and measured strain/stress or simulation targets are required for causal sharp-bumpâ†’strainâ†’tear claims)ro  ÚbranchesÚ
node_headsÚregion_headsÚidentifiabilityÚcurrent_dataÚphysics_neededÚ	completedzwsame prepared graph_6000 representation (requested ~6k; 5,925 actual nodes) for training, inference, viewer and outputsr2  r3  uY   BCE + Dice + 0.2Ã—signed-normal Huber + 0.2Ã—magnitude Huber against abs(normal residual))r.  r2  r3  Ú
loss_termsr1  ÚmetricsrÃ  z?diagnostic weak-label fit; not a physical tear/defect predictor)	ro  r¶  Úfixed_graphÚ
comparisonr�  ÚinputsrÃ  Úconceptual_next_modelr�  zreport.json)-Úallow_diagnostic_weak_labelsÚ
SystemExitr   r©   r±   rh  rM  Úlearning_rateÚMODELr‡   rî   ÚsaverE  ry   r®   ÚOUTrr   r‹   Úint32rÁ   ÚstackÚbool_r†   ÚexistsÚunlinkrŒ   r�   r�   r‘   r’   r²  ÚpltÚsubplotsÚplotÚ
set_yscaleÚlegendÚgridÚ	set_titleÚsavefigÚcloserL  ÚscatterÚ
set_aspectÚcolorbarr5  )r”   rÑ   rÒ   r   r•   rú   r×   r?   r›   r4   ÚcontractÚfigrÓ  rö   Úaxesrg  rÓ   rš   r    ÚcompÚconceptÚreports                         r5   r*  r*  ^   sq  € Ø	×&Ò&¬ZÐ8|Ó-}Ð'}ÜÔ”U“W�1¤%£'˜T°¨%Û
.€QÜˆAˆd�1�Q—X‘X˜aŸo™oÓ.�#€!€A¬u¯{©{À4ÐQU¨{Ô/VÔW\×WaÑWaÐpq×p|Ñp|Óp~ð  JKô  Y\ð  ]^ð  _dñ  ]eó  Yfð  wxð  yHñ  wIð  Z[ð  \kñ  Zlð  @Eñ  cFô  GLð  PQð  ORð  RYð  MZñ  GZô  X[ð  \a÷  \hñ  \hð  ijõ  \kð /ä‡��4 €Ô&Á%Ó)HÁ%¸Q¨!¨I©,°q©.À% qÐ)HÌ×I\ÑI\Ô]`ð  bNñ  ^Nð  Z[ð  \añ  Zbð  noð  pxñ  nyô  EG÷  EMñ  EMô  NQð  RSð  TYñ  RZó  N[ó  E\ô  df÷  dnñ  dnð  BGð  HIñ  BJð  KQò  BRó  oSñ  BRð  }~ð  pqð  rwó  pxð  BRñ  oSó  dTô  vx÷  v~ñ  v~ð  STð  Ufñ  Sgð  hnò  Soó  pñ  Soð  NOð  @Að  BHó  @Ið  Soñ  pó  vqô  LN÷  LTñ  LTð  ijð  k{ñ  i|ð  }Cò  iDó  UEñ  iDð  deð  VWð  X^ó  V_ð  iDñ  UEó  LFô  ac÷  aiñ  aið  @Að  BSñ  @Tð  U[ò  @\ó  j]ñ  @\ð  {|ð  klð  muó  kvð  @\ñ  j]ó  a^ô  rt÷  rzñ  rzð  Q	R	ð  S	c	ñ  Q	d	ð  e	k	ò  Q	l	ó  {m	ñ  Q	l	ð  L	M	ð  |}ð  ~F	ó  |G	ð  Q	l	ñ  {m	ó  rn	ô  L
N
÷  L
T
ñ  L
T
ð  h
i
ð  j
{
ñ  h
|
ð  }
Cò  h
Dó  U
Eñ  h
Dð  c
d
ð  V
W
ð  X
]
ó  V
^
ð  h
Dñ  U
Eó  L
Fô  ]_÷  ]eñ  ]eð  yzð  {Kñ  yLð  MSò  yTó  fUñ  yTð  tuð  ghð  inó  goð  yTñ  fUó  ]Vô  oq÷  owñ  owð  x|ó  o}õ  J~ÜÐ4Ñ4´SÐ9\Ñ5\Ô]`ð  bCñ  ^Cô  DGð  HVñ  DVô  W\ð  ]Bñ  WBô  CHð  Igñ  Cgô  hmð  nRñ  hRó  S€QØ‡X�X…Z�—‘•
ð SàAÐZ^ÔsvÐwxÐy~Ñwó  tAô  SVð  WXð  Y_ñ  W`÷  Wfñ  Wfð  ghñ  Wió  Sjð  OAð  afð  ypð  Lbð  qOñ  hmó  [nñ  hmð  cdð  \]ð  ^gñ  \hð  qrð  sBñ  qCð  KLð  M\ñ  K]ñ  i^ñ  \^ð  hmñ  [nñ  o€ô  qvð  wNñ  qN÷  pZñ  pZô  [_÷  [eñ  [eð  fnð  |Að  IJô  [Kð  U[ð  pZô  p\ô  ^að  btñ  ^t÷  ]@ñ  ]@ô  AE÷  AKñ  AKô  LPð  QRð  SXð  Y]ó  L^ð  lqð  }Fô  AGð  QWð  ]@ô  ]XÜ�‰˜WÔ%�€€Rñ  SXô  'Yñ  SXð  NO r§w¡wÀAÀiÂLÓ/QÁL¸q°°'³
ÀLÑ/QÐghÐirÒgsÓRtÑgsÐbcÐSTÐU\ÓS]ÐgsÑRtÐ{|ð  ~Gñ  |H wõ  (Ið  SXó  'Yð  Z\÷  Zgñ  Zgð  hmô  Znð  oq÷  oxñ  oxô  ozð  {}÷  {Bñ  {Bð  IKð  {Bô  {Lð  MO÷  MYñ  MYð  ZXô  MYð  Z]÷  Zeñ  Zeô  fið  jñ  fð  DGð  Zeô  ZHô  IL÷  IRñ  IRð  SVô  IWÜ
�,‰,�q˜ 6Ô
*�€€TÜ�eÖ�S€Q€qÜ�q˜‘yÖ!�c€aˆ D¨¨1¨¡I×$5Ñ$5°a¸±hºqÀ¸s±mÀAÀeÁHÊQÈqÈSÁMÐTUÐV\ÑT]Ð`aÐgnÐtuÐ{|Ð$5Ó$} !ð  Cð  DEð  FGð  DGñ  H÷  Rñ  Rð  VWð  Xañ  Vbð  Ucð  cdð  efð  glñ  emð  dnð  nsð  Stô  uð  vzð  {|ð  }~ð  {~ñ  v÷  vJñ  vJð  KRô  vSð  TW÷  T`ñ  T`ð  abð  fjð  klð  mnð  knñ  foð  T`õ  TpÑ!ð à‡�ŒSÐ0Ñ0°S€Ô9¼#¿)¹)ÀC¼.ô beð  fgð  hyñ  fzð  {Añ  fBð  CDð  EUñ  CVð  W]ñ  C^ô  b_ô  `ñ  b_ñ  [^ð  [\ð  ]^ˆa�‰h¨¨8©ÀaÈÁkÐghÐiqÑgrÐswÑgxÐyzð  |Dñ  zEð  FJñ  zKñ  hKð  bcð  dlñ  bmð  nzñ  b{ð  |}ð  ~Fñ  |Gð  HTñ  |Uñ  bUó  Vð  b_€ñ  `ð  sVð  bAð  Owð  G	k	ð  ~	Tð  d}ð  Omñ  inð  ahð  @Kð  _dð  slð  z~ñ  NSô  HTñ  NSð  IJð  TUð  V_ñ  T`ð  mnð  ozñ  m{ð  IJð  KWñ  IXð  fAð  LMð  NWñ  LXð  yzð  {Aò  yBó  cCñ  yBð  tuð  deð  fnó  doð  yBñ  cCó  IDð  NSò  HTð  ^fð  u}ð  ~Kñ  uLð  elð  |}ð  {~ñ  vð  ouô  ADð  ERñ  AR÷  @^ñ  @^ô  _c÷  _iñ  _ið  jpð  ~Cð  KLô  _Mð  W]ð  @^ô  @^ð  flð  _lùò *Iùò  oSùò  pùò  UEùò  j]ùò  {m	ùò  U
Eùò  fUùò [nùÚ/QùÒRtùó  'Yùó
 `ùò  cCùó  HTsx   Ã/YÅYÆYÆ,YÇYÈY!È-Y&ÉY+ ÌY0Î:Y?ÏY5Ï	Y?Ï&Y:Ï2Y?Ö	9Z×Z×5ZØZÙ5
Y?ÚZc                 ó&  — t        j                  «       } | j                  dd¬«       | j                  dt        d¬«       | j                  dt        d¬«       | j                  «       }t        t        j                  t        |«      d	d
¬«      «       y )Nz--allow-diagnostic-weak-labelsÚ
store_true)Úactionz--epochsé8   )ÚtypeÚdefaultz--learning-rategü©ñÒMb`?FrM   rd   )
ÚargparseÚArgumentParserÚadd_argumentrŒ   rŽ   Ú
parse_argsÚprintr‘   r’   r*  )r4   r”   s     r5   Úmainr  m   sí   € Ü×ÑÓ€˜QŸ^™^Ð,LÐT`˜^ÔaÐbc×bpÑbpÐq{ô  BEð  NPÐbpô  cQð  RS÷  R`ñ  R`ð  arô  x}ð  FJð  R`ô  RKð  NO÷  NZñ  NZó  N\ð  LMô  ]bô  cg÷  cmñ  cmô  nqð  rsó  ntð  BGð  OPô  cQõ  ]Rr7   Ú__main__)2Ú__doc__Ú
__future__r   r  r‘   r0   Úpathlibr   rK  rr   Úscipy.spatialr   rî   r   Útorch.nn.functionalÚ
functionalró   Ú
matplotlibÚuseÚmatplotlib.pyplotÚpyplotrï  Úmodels.datar   r	   r
   Úmodels.trainingr   ÚEXPr†   rç  ré  rÐ   rÁ   rŠ   r  r6   r©   r±   rÊ   rØ   ÚModulerÚ   r  r  rh  r²  r*  r  rý   © r7   r5   Ú<module>r     sú   ðÙ fÝ "ß Ó Ý Û Ý !Û Ý ß Ð Û �.�*—.‘. Ô'Ý ß JÑ JÝ +ØˆÑ€˜cÐ"3Ñ3˜¸#¸g¹+°EÈ#ÈiÉ-ÀcÐ^aÐX]Ø€b‡j�jò  mó  n€Ø€r‡z�zò  Eó  F€òò	~òòTòô
Bˆ"�)‰)ô BòCòCò]òyò,lòRàˆZÒ™�Ðr7   