§
    ÎÐj   ã                  ó¤   — d Z ddlmZ ddlZddlmZ ddlZdZdZe G d„ d¦  «        ¦   «         Zdd„Z	dd„Z
dd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS )a  Triangle mesh container shared by the 3D models, the file formats, the rasterizer and the renderer.

Conventions (those of glTF 2.0, so that a Mesh is written to GLB without conversion):
- Right-handed coordinates, +Y up, the front of the asset faces +Z (-X is the asset's right), units in metres.
- Faces are counter-clockwise seen from outside: the right-hand-rule normal (v1 - v0) x (v2 - v0) points outwards.
- One index buffer for every vertex attribute: vertices are duplicated along UV seams (and wherever an attribute differs).
- uvs: (0, 0) is the top-left corner of the texture image, u grows to the right and v downwards, so texel [r, c] of an
  [H, W, C] image covers u in [c / W, (c + 1) / W] and v in [r / H, (r + 1) / H]. OBJ/PLY files store 1 - v; their readers
  and writers convert.
- colors: per-vertex sRGB-encoded values in 0..1 (3 or 4 channels, alpha linear). The GLB writer stores them as linear
  COLOR_0, as glTF requires, and the GLB reader converts them back.
- base_color: uint8 sRGB texture [H, W, 3|4]; metallic_roughness: uint8 linear texture [H, W, 3] with G = roughness and
  B = metallic (R unused, the glTF packing); normal_map: uint8 linear tangent-space normal map [H, W, 3], OpenGL/glTF
  convention (+X red, +Y green, +Z blue). Image rows are stored top to bottom.
é    )ÚannotationsN)Ú	dataclass)ÚverticesÚnormalsÚuvsÚcolors)Ú
base_colorÚmetallic_roughnessÚ
normal_mapc                  ó    — e Zd ZU ded<   ded<   dZded<   dZded<   dZded<   dZded	<   dZded
<   dZ	ded<   e
dd„¦   «         Zdd„Zdd„ZdS )ÚMeshútorch.Tensorr   ÚfacesNztorch.Tensor | Noner   r   r   r	   r
   r   Úreturnútorch.devicec                ó   — | j         j        S ©N)r   Údevice)Úselfs    ú:C:\Users\johnn\OneDrive\Documents\AI\shared\mesh3d\mesh.pyr   zMesh.device'   s   € àŒ}Ô#Ð#ó    c                ó`   ‡ ‡‡— t          di ˆˆ ˆfd„t          j        ‰ ¦  «        D ¦   «         ¤ŽS )Nc                óx   •— i | ]6}|j         t          ‰|j         ¦  «        xŠ€d n‰                     ‰¦  «        “Œ7S r   )ÚnameÚgetattrÚto)Ú.0Úfr   r   Úts     €€€r   ú
<dictcomp>zMesh.to.<locals>.<dictcomp>,   sZ   ø€ ð  Að  Að  AÐbc�q”v­W°T¸1¼6Ñ-BÔ-BÐ(B¨Ð'K˜t˜tÐQR×QUÒQUÐV\ÑQ]ÔQ]ð  Að  Að  Ar   © )r   ÚdataclassesÚfields)r   r   r   s   ``@r   r   zMesh.to+   sk   øøø€ Ýð  Bð  Bð  Að  Að  Að  Að  Að  AÕgrÔgyÐz~ÑgÔgð  Añ  Aô  Að  Bð  Bð  	Br   c                ó&   — t          j        | fi |¤ŽS r   )r"   Úreplace)r   Úchangess     r   r%   zMesh.replace.   s   € ÝÔ" 4Ð3Ð3¨7Ð3Ð3Ð3r   )r   r   )r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r   r   r   r	   r
   r   Úpropertyr   r   r%   r!   r   r   r   r      sß   € € € € € € àÐÐÑØÐÐÑØ#'€GÐ'Ð'Ð'Ñ'Ø#€CÐ#Ð#Ð#Ñ#Ø"&€FÐ&Ð&Ð&Ñ&Ø&*€JÐ*Ð*Ð*Ñ*Ø.2ÐÐ2Ð2Ð2Ñ2Ø&*€JÐ*Ð*Ð*Ñ*àð$ð $ð $ñ „Xð$ðBð Bð Bð Bð4ð 4ð 4ð 4ð 4ð 4r   r   ÚmeshÚindexr   r   r   c                óH   ‡ ‡—  ‰ j         dd|iˆˆ fd„t          D ¦   «         ¤ŽS )zjMesh whose vertex i is the old vertex index[i] (every per-vertex attribute follows), with the given faces.r   c                ó^   •— i | ])}t          ‰|¦  «        ®|t          ‰|¦  «        ‰         “Œ*S r   )r   )r   Úkr-   r,   s     €€r   r    z#select_vertices.<locals>.<dictcomp>4   s<   ø€ Ð'zÐ'zÐ'zÀqÕ]dÐeiÐklÑ]mÔ]mÐ]y¨­7°4¸Ñ+;Ô+;¸EÔ+BÐ]yÐ]yÐ]yr   r!   )r%   ÚVERTEX_FIELDS)r,   r-   r   s   `` r   Úselect_verticesr2   2   s9   øø€ àˆ4Œ<Ð{Ð{˜eÐ{Ð'zÐ'zÐ'zÐ'zÐ'zÍMÐ'zÑ'zÔ'zÐ{Ð{Ð{r   Ú	face_maskc                ól   — t          j        | j        |         d¬¦  «        \  }}t          | ||¦  «        S )ziKeeps the selected faces (bool mask or indices) and only the vertices they use (in their original order).T)Úreturn_inverse)ÚtorchÚuniquer   r2   )r,   r3   Úusedr   s       r   Úsubmeshr9   7   s3   € å”,˜tœz¨)Ô4ÀTÐJÑJÔJ�K€Dˆ%Ý˜4  uÑ-Ô-Ð-r   r   ú!tuple[torch.Tensor, torch.Tensor]c                ó"  — | j         rt          j        | dd¬¦  «        S |                      ¦   «         dz  }| dz                        t          t          d|› �¦  «        ¦  «        }|||dz
  z	  d|dz
  z  dz
  z  z  }t          j        t          | ¦  «        ¦  «        }t          t          | j
        d         ¦  «        ¦  «        D ]+}|t          j        |||f         d¬¦  «        j                 }Œ,||         }t          j        t          |¦  «        t          j        ¬	¦  «        }|dd
…         |d
d…         k                         d¦  «        |dd
…<   t          j        |¦  «        }t          j        |d¦  «        dz
  ||<   | ||                  |fS )a…  Unique positions (exact float equality, -0.0 == 0.0) in lexicographic order and, for each vertex, the index of its unique
    position: torch.unique(vertices, dim=0, return_inverse=True). On the CPU, where torch.unique compares rows one by one (seconds for
    large meshes), the rows are ordered by stable radix sorts of integer keys that order like the coordinates, one column at a time.r   T)Údimr5   é   ç        Úinté   )Ústable©ÚdtypeNéÿÿÿÿ)Úis_cudar6   r7   Úelement_sizeÚviewr   ÚarangeÚlenÚreversedÚrangeÚshapeÚsortÚindicesÚonesÚboolÚanyÚ
empty_likeÚcumsum)r   ÚwidthÚkeysÚorderÚaxisÚfirstÚinverses          r   ÚweldrZ   =   s�  € ð Ôð BÝŒ|˜H¨!¸DÐAÑAÔAÐAØ×!Ò!Ñ#Ô# aÑ'€EØ�s‰N× Ò ¥­°°e°°Ñ!>Ô!>Ñ?Ô?€DØ�D˜U Q™YÑ'¨Q°5¸1±9Ñ-=ÀÑ,BÑCÑD€DÝŒL�˜X™œÑ'Ô'€EÝ�˜xœ~¨aÔ0Ñ1Ô1Ñ2Ô2ð Jð JˆØ•e”j  e¨T kÔ!2¸4Ð@Ñ@Ô@ÔHÔIˆˆØ�Œ;€DÝŒJ•s˜5‘z”z­¬Ð4Ñ4Ô4€EØ�a�b�b”˜T # 2 #œYÒ&×+Ò+¨AÑ.Ô.€Eˆ!ˆ"ˆ"�IÝÔ˜uÑ%Ô%€GÝ”\ %¨Ñ+Ô+¨aÑ/€GˆE�NØ�E˜%”LÔ! 7Ð*Ð*r   c                ó®   — | |         }t           j                             |dd…df         |dd…df         z
  |dd…df         |dd…df         z
  ¦  «        S )zUUnnormalized face normals (v1 - v0) x (v2 - v0); their length is twice the face area.Nr@   r   é   )r6   ÚlinalgÚcross)r   r   Úvs      r   Úface_normalsr`   Q   s]   € à�Œ€AÝŒ<×Ò˜a    1 œg¨¨!¨!¨!¨Q¨$¬Ñ/°°1°1°1°a°4´¸1¸Q¸Q¸QÀ¸T¼7Ñ1BÑCÔCÐCr   c                ó  — t          | ¦  «        \  }}t          |                      ¦   «         |¦  «                             dd¦  «        }t	          j        |t          j        ¬¦  «                             d||                              d¦  «        |¦  «        |         }| 	                    dd¬¦  «        }t	          j
        g d¢| j        ¬	¦  «        }t	          j        |dk    ||                     d
¦  «        z  |¦  «        S )zÂArea-weighted unit vertex normals, smooth across vertices that share a position (UV seams). Vertices without any
    non-degenerate face get +Y, so that the result is always a valid glTF NORMAL.é   r   rB   rD   r@   T)r<   Úkeepdim)r>   g      ð?r>   )r   g ÂëþKH´9)rZ   r`   ÚfloatÚrepeat_interleaver6   Ú
zeros_likeÚfloat32Ú
index_add_ÚreshapeÚnormÚtensorr   ÚwhereÚ	clamp_min)r   r   ÚweldedrY   Úcorner_normalsÚsumsÚlengthÚups           r   Úvertex_normalsrs   W   sÚ   € õ ˜8‘n”n�O€FˆGÝ! (§.¢.Ñ"2Ô"2°EÑ:Ô:×LÒLÈQÐPQÑRÔR€NÝÔ˜F­%¬-Ð8Ñ8Ô8×CÒCÀAÀwÈuÄ~×G]ÒG]Ð^`ÑGaÔGaÐcqÑrÔrÐszÔ{€DØ�YŠY˜1 dˆYÑ+Ô+€FÝ	Œ�o�o�o¨h¬oÐ	>Ñ	>Ô	>€BÝŒ;�v ’z 4¨&×*:Ò*:¸5Ñ*AÔ*AÑ#AÀ2ÑFÔFÐFr   c                óV   — |                       d¦  «        |                      d¦  «        fS )Nr   )ÚaminÚamax)r   s    r   Úbounding_boxrw   b   s%   € Ø�=Š=˜ÑÔ˜XŸ]š]¨1Ñ-Ô-Ð-Ð-r   Úxc                ót   — t          j        | dk    | dz  |                      d¦  «        dz   dz  dz  ¦  «        S )z@sRGB transfer function decode (IEC 61966-2-1) of values in 0..1.g?ÆÜµ¤?ç×£p=
×)@ç)\�Âõ(¬?çáz®Gáð?g333333@©r6   rl   rm   ©rx   s    r   Úsrgb_to_linearr   f   s;   € åŒ;�q˜G’| Q¨¡Y°!·+²+¸gÑ2FÔ2FÈÑ2NÐRWÑ1WÐ\_Ñ0_Ñ`Ô`Ð`r   c                ót   — t          j        | dk    | dz  d|                      d¦  «        dz  z  dz
  ¦  «        S )z7sRGB transfer function encode of linear values in 0..1.g·‡sÃ¥i?rz   r|   g«ªªªªªÚ?r{   r}   r~   s    r   Úlinear_to_srgbr�   k   s;   € åŒ;�q˜I’~ q¨5¡y°%¸!¿+º+ÀiÑ:PÔ:PÐU\Ñ:]Ñ2]Ð`eÑ2eÑfÔfÐfr   )r,   r   r-   r   r   r   r   r   )r,   r   r3   r   r   r   )r   r   r   r:   )r   r   r   r   r   r   )rx   r   r   r   )Ú__doc__Ú
__future__r   r"   r   r6   r1   ÚTEXTURE_FIELDSr   r2   r9   rZ   r`   rs   rw   r   r�   r!   r   r   ú<module>r…      sH  ððð ð #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ø !Ð !Ð !Ð !Ð !Ð !à €€€à8€ØC€ð ð4ð 4ð 4ð 4ð 4ñ 4ô 4ñ „ð4ð*|ð |ð |ð |ð
.ð .ð .ð .ð+ð +ð +ð +ð(Dð Dð Dð DðGð Gð Gð Gð.ð .ð .ð .ðað að að að
gð gð gð gð gð gr   