Ë
    :vžj€“  ã                   ó2  — 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m	Z	 ddl
mZmZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZ i d
d“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“d d!“d"d#“d$d!“d%d%d&œ¥Zd
dddddddd d"d'd(œZd)„ Z	 	 	 	 dCd*edz  d+ed,edz  d-efd.„Zd/„ Zd0„ Zd1„ Zd2„ Z 	 	 	 dDd3edz  d4efd5„Z!d6„ Z"dEd7„Z#d8„ Z$d9„ Z%d:„ Z&d;„ Z'd<„ Z(dFd=„Z)d>„ Z*d?eiZ+d?e!iZ, ejZ                  d@«      Z. ejZ                  dA«      Z/e/�e*e+dB<   e.�e)e,dB<   yy)Gé    N)ÚTemplate)Ústructured_to_unstructuredÚunstructured_to_structuredé   )ÚgroupingÚ	resourcesÚutilÚvisual)Úlog)Útriangulate_quads)ÚResolver)Ú	ArrayLikeÚcharÚi1ÚucharÚu1ÚshortÚi2ÚushortÚu2ÚintÚi4Úint8Úint16Úint32Úint64Úi8ÚuintÚu4Úuint8Úuint16Úuint32Úuint64Úu8ÚfloatÚf4Úfloat16Úf2Úfloat32Úf8)Úfloat64Údoubler,   )r   r   r   r   r   r   r   r$   r&   r(   r*   c                 ó.   — t         | j                  dd    S )z®
    Returns the closest ply equivalent of a numpy type

    Parameters
    ---------
    _numpy_type : a numpy datatype

    Returns
    ---------
    ply_type : string
    é   N)Ú_inverse_dtypesÚstr)Ú_numpy_types    úe/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/trimesh/exchange/ply.pyÚ_numpy_type_to_ply_typer3   6   s   € ô ˜;Ÿ?™?¨1¨2Ð.Ñ/Ð/ó    ÚresolverÚfix_textureÚprefer_colorÚskip_materialsc                 ó–  — t        | «      \  }}}	|rt        || «       nt        || «       d}
|sF	 ddl}|	�?|j	                  |	«      }|j
                  j                  t        j                  |«      «      }
t        |
|||¬«      }|S # t        $ r t        j                  d«       Y Œ1t        $ r t        j                  dd¬«       Y ŒRw xY w)a–  
    Load a PLY file from an open file object.

    Parameters
    ---------
    file_obj : an open file- like object
      Source data, ASCII or binary PLY
    resolver
      Object which can resolve assets
    fix_texture
      If True, will re- index vertices and faces
      so vertices with different UV coordinates
      are disconnected.
    skip_materials
      If True, will not load texture (if present).
    prefer_color
      None, 'vertex', or 'face'
      Which kind of color to prefer if both defined

    Returns
    ---------
    mesh_kwargs : dict
      Data which can be passed to
      Trimesh constructor, eg: a = Trimesh(**mesh_kwargs)
    Nr   z%textures require `pip install pillow`zunable to load image!T©Úexc_info)ÚimageÚelementsr6   r7   )Ú_parse_headerÚ
_ply_asciiÚ_ply_binaryÚ	PIL.ImageÚgetÚImageÚopenr	   Úwrap_as_streamÚImportErrorr   ÚdebugÚBaseExceptionÚwarningÚ_elements_to_kwargs)Úfile_objr5   r6   r7   r8   ÚargsÚkwargsr=   Úis_asciiÚ
image_namer<   ÚPILÚdatas                r2   Úload_plyrR   E   sÈ   € ôH &3°8Ó%<Ñ"€Hˆh˜
ñ Ü�8˜XÕ&ä�H˜hÔ'ð €EÙð	@ãð Ð%Ø—|‘| JÓ/�ØŸ	™	Ÿ™¤t×':Ñ':¸4Ó'@ÓA�ô !Ø˜h°KÈlô€Fð €Møô ò 	?Ü�I‰IÐ=Ö>Üò 	@Ü�K‰KÐ/¸$×?ð	@ús   °AB ÂCÂ&CÃCc                 ó  — |j                  «       D ]k  \  }}|j                  j                  d«      }|j                  dkD  r)| j	                  |› d�df|||j
                  d   fg«       ŒY| j                  ||f«       Œm | S )a!  
    Parses attribute datatype to populate a numpy dtype list

    Parameters
    ----------
    dtype : list of numpy datatypes
      operated on in place
    attributes : dict
      contains all the attributes to parse

    Returns
    ----------
    dtype : list of numpy datatypes
    Ú<r.   Ú_countú<u1)ÚitemsÚdtypeÚnewbyteorderÚndimÚextendÚshapeÚappend)rX   Ú
attributesÚnamerQ   Úfield_dtypes        r2   Ú_add_attributes_to_dtypera   ‰   s~   € ð !×&Ñ&Ö(‰
ˆˆdà—j‘j×-Ñ-¨cÓ2ˆØ�9‰9�qŠ=Ø�L‰L˜d˜V 6˜?¨EÐ2°T¸;ÈÏ
É
ÐSTÉÐ4VÐWÕXà�L‰L˜$ Ð,Õ-ð )ð €Lr4   c                 ó  — |j                  «       D ]k  \  }}|j                  dk(  r,| j                  dt        |j                  «      › d|› d�«       ŒA| j                  dt        |j                  «      › d|› d�«       Œm | S )a'  
    Parses attributes in to ply header entries

    Parameters
    ----------
    header : list of ply header entries
      operated on in place
    attributes : dict
      contains all the attributes to parse

    Returns
    ----------
    header : list
      Contains ply header entries
    r.   z	property Ú Ú
zproperty list uchar )rW   rZ   r]   r3   rX   )Úheaderr^   r_   rQ   s       r2   Ú_add_attributes_to_headerrf   ¢   s~   € ð  !×&Ñ&Ö(‰
ˆˆdØ�9‰9˜Š>Ø�M‰M˜IÔ&=¸d¿j¹jÓ&IÐ%JÈ!ÈDÈ6ÐQSÐTÕUà�M‰MØ&Ô'>¸t¿z¹zÓ'JÐ&KÈ1ÈTÈFÐRTÐUõð	 )ð €Mr4   c                 óÎ   — |j                  «       D ]Q  \  }}|j                  dkD  r8|j                  d   t        j                  |j                  d   «      z  | |› d�<   || |<   ŒS | S )a“  
    Parses attribute data in to a custom array, assumes datatype has been defined
    appropriately

    Parameters
    ----------
    data_array : numpy array with custom datatype
      datatype reflects all the data to be stored for a given ply element
    attributes : dict
      contains all the attributes to parse

    Returns
    ----------
    data_array : numpy array with custom datatype
    r.   r   rU   )rW   rZ   r\   ÚnpÚones)Ú
data_arrayr^   r_   rQ   s       r2   Ú_add_attributes_to_data_arrayrk   ¼   sf   € ð  !×&Ñ&Ö(‰
ˆˆdØ�9‰9�qŠ=Ø*.¯*©*°Q©-¼"¿'¹'À$Ç*Á*ÈQÁ-Ó:PÑ*PˆJ˜$˜˜v�Ñ'Øˆ
�4Òð )ð Ðr4   c                 ó¢   — | j                  «       D ]<  }|j                  dvrt        d«      ‚|j                  j                  €Œ3t        d«      ‚ y)zó
    Asserts that a set of attributes is valid for PLY export.

    Parameters
    ----------
    attributes : dict
      Contains the attributes to validate

    Raises
    --------
    ValueError
      If passed attributes aren't valid.
    )r.   r   z/PLY attributes are limited to 1 or 2 dimensionsNz+PLY attributes must be of a single datatype)ÚvaluesrZ   Ú
ValueErrorrX   Únames)r^   rQ   s     r2   Ú_assert_attributes_validrp   Ó   sM   € ð ×!Ñ!Ö#ˆØ�9‰9˜FÑ"ÜÐNÓOÐOð �:‰:×ÑÑ'ÜÐJÓKÐKñ $r4   Úvertex_normalÚinclude_attributesc           	      ó¼  — |dk(  rd}n|dvrt        d«      ‚|€d| j                  v }|rùt        | d«      rÌt        | d«      r«t        | j                  d	«      r•t	        j
                  | j                  j                  «      t        | j                  «      d
fk(  rT| j                  j                  dd…df   | j                  d<   | j                  j                  dd…df   | j                  d<   t        | j                  «       t        | d«      rt        | j                  «       ddg}dg}d}d}dg}t        j                  d«      }	|	d   g}
d|i}d}d}d}t        | d«      �r3t        | j                  «      r'| j                  j
                  d   dk7  rt        d«      ‚t        | j                  «      dkD  �r¬| j                  D �cg c]  }|j                  | j                  «      ‘Œ }}t	        j                   |D �cg c]  }|j
                  d   ‘Œ c}«      }t	        j"                  dgt	        j$                  |«      dd f«      }|j'                  «       }t	        j(                  t	        j*                  d|dz
  «      t	        j*                  d|«      f«      }t	        j,                  t/        |dz
  |«      D ��cg c]  \  }}|d| |z   ‘Œ c}}«      }t	        j,                  |«      }t        |«      }t        |«      }|dkD  �r^|dkD  �rX|
j1                  |	d   «       t	        j2                  ||¬«      }t	        j4                  |t        j6                  ¬«      |d<   |
j1                  |	d   «       t9        ||¬«      }|j;                  ||d œ«       �nÎt        | d!«      �rÁ|
j1                  |	d   «       t        | j                  «      }||d"<   |r%|
j1                  |	d#   «       |j1                  |«       t        | d«      xrP | j                  j<                  dk(  xr5 t        | j                  j>                  «      t        | j                  «      k(  }|r%|
j1                  |	d$   «       |j1                  |«       |rƒt        | d«      rut        | j                  «      }| j                  jA                  «       D ��ci c]"  \  }}t        |d%«      rt        |«      |k(  r||“Œ$ } }}tC        |
| «       tE        || «       nd} t	        j2                  ||¬«      }| j                  |d<   |r| jF                  |d&<   |r| j                  j>                  |d'<   |r �tI        || «       t        | d(«      �rB|
j1                  |	d)   «       | j                  j<                  d)k(  r*|d*k7  r%|
j1                  |	d$   «       |j1                  |«       |r8t        | d«      r,tC        |
| j                  «       tE        || j                  «       t	        j2                  t        | jJ                  «      |¬«      }d|d+<   | jJ                  |d,<   | j                  j<                  d)k(  r|d*k7  r| j                  jL                  |d'<   t        | jJ                  «      |d-<   |r"t        | d«      rtI        || j                  «       |
j1                  |	d.   «       tO        d/jQ                  |
«      «      jS                  |«      jU                  d0«      g}!|dk(  rd|�|!j1                  |jW                  «       «       |�|!j1                  |jW                  «       «       |�î|!j1                  |jW                  «       «       nÎ|d*k(  r¾|�6|!j1                  tY        jZ                  |d1d2¬3«      jU                  d0«      «       |�8|!j]                  d4tY        jZ                  |d1d2¬3«      jU                  d0«      g«       |�8|!j]                  d4tY        jZ                  |d1d2¬3«      jU                  d0«      g«       |!j1                  d4«       nt        d5«      ‚d6jQ                  |!«      S c c}w c c}w c c}}w c c}}w )7a/  
    Export a mesh in the PLY format.

    Parameters
    ----------
    mesh : trimesh.Trimesh
      Mesh to export.
    encoding : str
      PLY encoding: 'ascii' or 'binary_little_endian'
    vertex_normal : None or include vertex normals

    Returns
    ----------
    export : bytes of result
    ÚbinaryÚbinary_little_endian)ru   Úasciiz encoding must be binary or asciiNÚvertex_normalsÚvertex_attributesr
   Úuvr   r   Úsr.   ÚtÚface_attributes)ÚcountrV   )Úindexú<i4é   )Úvertexú<f4r€   )Únormalsr‚   r€   )ÚrgbarV   é   )r~   r   r   ztemplates/ply.jsonÚintroÚencodingÚentitieséÿÿÿÿr€   z'only Path3D export is supported for plyr�   ©rX   Úedge)Ú
edge_countÚvertex_countÚverticesr�   rq   ÚcolorÚ__len__rƒ   r„   ÚfacesÚfacerv   r}   r~   Ú
face_countÚoutroÚ úutf-8rc   rd   )Ú	col_delimÚ	row_delimó   
z!encoding must be ascii or binary!r4   )/rn   Ú_cacheÚhasattrr
   rh   r\   ry   ÚlenrŽ   rx   rp   r|   r   Úget_jsonrˆ   ÚdiscreteÚarrayÚconcatenateÚcumsumÚmaxÚcolumn_stackÚarangeÚvstackÚzipr]   ÚzerosÚasarrayr)   r   ÚupdateÚkindÚvertex_colorsrW   rf   ra   rw   rk   r‘   Úface_colorsr   ÚjoinÚ
substituteÚencodeÚtobytesr	   Ústructured_array_to_stringr[   )"Úmeshr‡   rq   rr   Ú
dtype_faceÚdtype_vertexÚdtype_vertex_normalÚdtype_colorÚ
dtype_edgeÚ	templatesre   Úheader_paramsÚ
pack_edgesÚpack_vertexÚ
pack_facesÚerž   ÚdÚdiscrete_lenÚdiscrete_offÚlongestÚstackÚlengthÚoffsetÚedgesrŽ   Únum_verticesÚ	num_edgesÚvertex_colorr�   ÚkÚvrx   Úexports"                                     r2   Ú
export_plyrÌ   ê   s�  € ð. �8ÒØ)‰Ø	Ð:Ñ	:ÜÐ;Ó<Ð<ð ÐØ(¨D¯K©KÐ7ˆñ Ü�4Ð,Ô-ô ˜˜hÔ'Ü˜DŸK™K¨Ô.Ü—H‘H˜TŸ[™[Ÿ^™^Ó,´°T·]±]Ó1CÀQÐ0GÒGà.2¯k©k¯n©nºQÀ¸TÑ.B�×&Ñ& sÑ+Ø.2¯k©k¯n©nºQÀ¸TÑ.B�×&Ñ& sÑ+Ü$ T×%;Ñ%;Ô<Ü�4Ð*Ô+Ü$ T×%9Ñ%9Ô:ð #Ð$9Ð:€JØ*Ð+€Là1ÐØ&€Kà'Ð(€Jô ×"Ñ"Ð#7Ó8€Ià˜Ñ Ð!€FØ Ð*€Mð $(€JØ$(€KØ#'€Jô ˆt�ZÕ Üˆt�}‰}Ô $§-¡-×"5Ñ"5°bÑ"9¸QÒ">ÜÐFÓGÐGäˆt�}‰}Ó Ó!à;?¿=º=ÓI¹=°a˜Ÿ
™
 4§=¡=Õ1¸=ˆHÐIô Ÿ8™8¹Ó$B¹°A Q§W¡W¨Q£Z¸Ñ$BÓCˆLäŸ>™>¨A¨3´·	±	¸,Ó0GÈÈÐ0LÐ*MÓNˆLð #×&Ñ&Ó(ˆGÜ—O‘O¤R§Y¡Y¨q°'¸A±+Ó%>ÄÇ	Á	È!ÈWÓ@UÐ$VÓWˆEô —I‘Iô +.¨l¸QÑ.>ÀÔ*Môá*M™˜ ð ˜'˜6�N VÓ+Ø*MòóˆEô —y‘y Ó*ˆHä˜x›=ˆLä˜E›
ˆIà˜1‹} °Ó!1Ø—‘˜i¨Ñ1Ô2Ü Ÿh™h |¸<ÔH�Ü(*¯
©
°8Ä2Ç:Á:Ô(N�˜HÑ%ð —‘˜i¨Ñ/Ô0ä7¸ÀZÔP�
ð ×$Ñ$Ø#,¸lÑKöô 
��zÕ	"Ø�‰�i Ñ)Ô*ä˜4Ÿ=™=Ó)ˆØ(4ˆ�nÑ%ñ Ø�M‰M˜) OÑ4Ô5Ø×ÑÐ 3Ô4ô �D˜(Ó#ò EØ—‘× Ñ  HÑ,òEä�D—K‘K×-Ñ-Ó.´#°d·m±mÓ2DÑDð 	ñ
 Ø�M‰M˜) GÑ,Ô-Ø×Ñ Ô,áÜ�tÐ0Ô1Ü" 4§=¡=Ó1�ð !%× 6Ñ 6× <Ñ <Ô >ô%á >™˜˜1Ü˜q )Ô,´°Q³¸<Ò1Gð �q‘DØ >ð "ñ %ô
 *¨&Ð2CÔDÜ(¨Ð7HÕIà$(Ð!ô —h‘h˜|°<Ô@ˆØ $§¡ˆ�HÑÙØ%)×%8Ñ%8ˆK˜	Ñ"ÙØ"&§+¡+×";Ñ";ˆK˜ÑáÐ"3Ð"?Ü)¨+Ð7HÔIäˆt�WÕØ�‰�i Ñ'Ô(Ø�;‰;×Ñ˜vÒ%¨(°gÒ*=Ø�M‰M˜) GÑ,Ô-Ø×Ñ˜kÔ*á¤'¨$Ð0AÔ"BÜ% f¨d×.BÑ.BÔCÜ$ Z°×1EÑ1EÔFô —X‘Xœc $§*¡*›o°ZÔ@ˆ
Øˆ
�7ÑØ"Ÿj™jˆ
�7ÑØ�;‰;×Ñ˜vÒ%¨(°gÒ*=Ø!%§¡×!8Ñ!8ˆJ�vÑÜ&)¨$¯*©*£oˆ�lÑ#á¤'¨$Ð0AÔ"BÜ)¨*°d×6JÑ6JÔKà
‡M�M�)˜GÑ$Ô%Ü�r—w‘w˜v“Ó'×2Ñ2°=ÓA×HÑHÈÓQÐR€FàÐ)Ò)ØÐ"Ø�M‰M˜+×-Ñ-Ó/Ô0ØÐ!Ø�M‰M˜*×,Ñ,Ó.Ô/ØÐ!Ø�M‰M˜*×,Ñ,Ó.Õ/Ø	�WÒ	ØÐ"Ø�M‰MÜ×/Ñ/Ø¨3¸$ôç‘&˜“/ôð Ð!Ø�M‰MàÜ×3Ñ3Ø"¨c¸Tôç‘f˜W“oð	ôð Ð!Ø�M‰MàÜ×3Ñ3Ø"¨c¸Tôç‘f˜W“oð	ôð 	�‰�eÕô Ð<Ó=Ð=à�8‰8�FÓÐùòi Jùò %Cùóùóf%s   Ç"aÇ=aÊ;a
Ò='ac                 óð  — dt        | j                  «       «      j                  «       vrt        d«      ‚| j                  «       j	                  d«      j                  «       j                  «       }d|v }ddgt        d|v «         }t        j                  «       }d}	 | j                  «       }|€t        d	«      ‚|j	                  d«      j                  «       }|j                  «       }d
|v r�nd|d   v r,|dd \  }}	t        |	«      t        j                  «       dœ||<   nÏd|d   v r�|st        d«      ‚t        |«      dk(  r'|dd \  }
}|t        |
   z   |   d   t        |«      <   n†d|d   v r|dd \  }}
}|t        |   z   dz   |z   t        |
   z   |   d   t        |«      <   nGd|j                  «       v r5|j                  «       j                  d«      dz   }||d j                  «       }�ŒV|||fS )aÔ  
    Read the ASCII header of a PLY file, and leave the file object
    at the position of the start of data but past the header.

    Parameters
    -----------
    file_obj : open file object
      Positioned at the start of the file

    Returns
    -----------
    elements : collections.OrderedDict
      Fields and data types populated
    is_ascii : bool
      Whether the data is ASCII or binary
    image_name : None or str
      File name of TextureFile
    ÚplyzNot a ply file!r–   rv   rT   Ú>ÚbigNzHeader not terminated properly!Ú
end_headerÚelementr   r.   )rÃ   Ú
propertiesÚpropertyz$Property defined before any element!r€   rÓ   Úlistr   z
, ($LIST,)Útexturefileé   )r0   ÚreadlineÚlowerrn   ÚdecodeÚstripr   ÚcollectionsÚOrderedDictÚsplitrœ   Ú_dtypesr~   )rK   r‡   rN   Úendianr=   rO   ÚrawÚliner_   rÃ   rX   ÚfieldÚdtype_countr~   s                 r2   r>   r>   Ì  s+  € ð( ”C˜×)Ñ)Ó+Ó,×2Ñ2Ó4Ñ4ÜÐ*Ó+Ð+ð × Ñ Ó"×)Ñ)¨'Ó2×8Ñ8Ó:×@Ñ@ÓB€HØ˜(Ð"€Hð �3ˆZœ˜E XÐ-Ó.Ñ/€FÜ×&Ñ&Ó(€Hð €Jà
Ø×ÑÓ!ˆØˆ;ÜÐ>Ó?Ð?Ø�j‰j˜Ó!×'Ñ'Ó)ˆØ�y‰y‹{ˆð ˜4ÑÙð ˜˜Q™Ñà  ˜8‰LˆD�&ä˜f›+Ü)×5Ñ5Ó7ñˆH�TŠNð
 ˜4 ™7Ñ"ñ Ü Ð!GÓHÐHô �4‹y˜AŠ~Ø# A B˜x‘��uØ;AÄGÈEÁNÑ;R�˜‘˜|Ñ,¬S°«ZÒ8ð ˜4 ™7Ñ"Ø,0°°¨HÑ)�˜U EàœW [Ñ1Ñ1°LÑ@À6ÑIÌGÐTYÉNÑZð ˜‘˜|Ñ,¬S°«ZÒ8ð ˜cŸi™i›kÑ)ð —I‘I“K×%Ñ% mÓ4°rÑ9ˆEà˜U˜V˜×*Ñ*Ó,ˆJñY ð\ �X˜zÐ)Ð)r4   c                 óè
  — dd| ii}d| v rU| d   d   rMt        j                  dD �cg c]  }| d   d   |   ‘Œ c}«      }t        j                  |d«      st	        d«      ‚i |d	<   |S 	 t        j                  d
D �cg c]  }| d   d   |   ‘Œ c}«      }t        |«      t        |«      k(  r||d<   d| v r| d   d   r	| d   d   }	nd}	d}
ddg}d}t        j                  |	d«      r|	}
nàt        |	t        «      r|D ]  }||	v sŒ|	|   }
 n d|	v rº|	d   }n´t        |	t         j                  «      rš| d   d   }t        |j                  j                  «      dk(  r|j                  j                  d   }nEt        |j                  j                  «      dkD  r#|j                  j                  D ]
  }||v sŒ|} n |   d   }
	 |d   d   }
��1t        j                  |
«      }t        |«      dk7  rt        |
«      }
|€„g d¢}|D ]{  }	 | d   d   |d      }| d   d   |d      }t        j                  ||
j!                  d«         ||
j!                  d«         fd¬«      j!                  |
j                  d   df«      } n t        j                  |
«      }|��	t        |«      dk(  rû|j                  |
j                  d   |
j                  d   dz  fk(  rÍ|rcddlm} |j!                  d«      }t'        j(                  |«      \  }} ||
|j!                  |
j                  «      «      \  }
}}||   }||   |   }nCt        j*                  t        |«      df«      }|j!                  d«      ||
j!                  d«      <   t,        j.                  j1                  ||¬«      |d<   nW|�Uddlm} t        j*                  t        |«      df«      }|j!                  d«      ||
j!                  d«      <    ||¬«      |d<   |
|d<   ||d <   d| v rt3        | d   «      |d!<   d| v rt3        | d   «      |d"<   | j5                  d#i «      j5                  dd«      }|�¦d}t        |t        «      r	 t        j                  |d$   |d%   f«      }nRt        |t         j                  «      r8t        |j                  «      dk(  r|j                  d   dk(  r|}nt=        |«      }|�!dd)lm } |jC                   |||d    «      «       |S c c}w c c}w # t        $ r Y �Œ]w xY w# t        t        f$ r Y �Œ[w xY w# t        t        f$ r Y �Œ8w xY w# t        $ r+ t7        j8                  d&|j;                  «       › �d'¬(«       Y Œžw xY w)*a`  
    Given an elements data structure, extract the keyword
    arguments that a Trimesh object constructor will expect.

    Parameters
    ------------
    elements : OrderedDict object
      With fields and data loaded
    fix_texture : bool
      If True, will re- index vertices and faces
      so vertices with different UV coordinates
      are disconnected.
    image : PIL.Image
      Image to be viewed
    prefer_color : None, 'vertex', or 'face'
      Which kind of color to prefer if both defined

    Returns
    -----------
    kwargs : dict
      Keyword arguments for Trimesh constructor
    ÚmetadataÚ_ply_rawr�   rÃ   ÚxyzrQ   )r‰   r€   zVertices were not (n,3)!Úgeometry)ÚnxÚnyÚnzrw   r’   NÚvertex_indexÚvertex_indices)r‰   )r€   r…   Útexcoordr.   r   Úf1r   ))Ú	texture_uÚ	texture_v)ÚurÊ   )rz   r{   r‰   )Úaxis)Úunmerge_faces)r‰   r   )ry   r<   r
   )ÚTextureVisuals)ry   r‘   rŽ   r¬   r«   r‹   Úvertex1Úvertex2z'failed to convert PLY edges from keys: Tr:   )Úedges_to_path)"rh   r£   r	   Úis_shapern   rœ   rH   Ú
isinstanceÚdictÚndarrayrX   ro   ÚKeyErrorr\   r   rÂ   ÚreshapeÚvisual.texturerõ   r   Úunique_rowsr§   r
   Útexturerö   Ú_element_colorsrB   r   rG   Úkeysr   Úpath.exchange.miscrù   r©   )r=   r6   r<   r7   rM   ÚirŽ   Újrw   Ú	face_datar‘   Úindex_namesrï   Ú	face_blobr_   r\   Útexcoord_namesro   Út_uÚt_vrõ   Úuv_allÚuniqueÚinverseÚmask_vÚmask_vtry   rö   Ú	edge_datarÅ   rù   s                                  r2   rJ   rJ     sÂ  € ð0 ˜: xÐ0Ð1€Fà�8Ñ ¨Ñ 2°8Ò <Ü—?‘?É5Ó#QÉ5Àa H¨XÑ$6°vÑ$>¸qÓ$AÈ5Ñ#QÓRˆÜ�}‰}˜X wÔ/ÜÐ7Ó8Ð8ð  ˆˆzÑØˆðÜŸ™Ù4FÓGÑ4F¨qˆX�hÑ Ñ'¨Ó*Ð4FÑGó
ˆô ˆ~Ó¤# h£-Ò/Ø'5ˆFÐ#Ñ$ð �Ñ˜h vÑ.¨xÒ8Ø˜VÑ$ VÑ,‰	ð ˆ	Øˆð "Ð#3Ð4€KØ€Hä‡}�}�Y Ô-Ø‰Ü	�IœtÔ	$ãˆAØ�IŠ~Ø! !™�Ùð ð
 ˜Ñ"Ø  Ñ,‰Hä	�IœrŸz™zÔ	*Ø˜VÑ$ VÑ,ˆ	ô ˆy�‰×$Ñ$Ó%¨Ò*Ø—?‘?×(Ñ(¨Ñ+‰DÜ�—‘×&Ñ&Ó'¨!Ò+à—_‘_×*Ô*�Ø˜Ò#Ø�DÙð +ð
 ˜$‘ Ñ%ˆð	Ø  Ñ,¨TÑ2ˆHð ÑÜ—‘˜“ˆÜˆu‹:˜Š?ä% eÓ,ˆEàÐò RˆNÛ'�ð
Ø" 8Ñ,¨VÑ4°U¸1±XÑ>�CØ" 8Ñ,¨VÑ4°U¸1±XÑ>�CÜ!Ÿx™xØ˜UŸ]™]¨2Ó.Ñ/°°U·]±]À2Ó5FÑ1GÐHÈrô ç‘g˜uŸ{™{¨1™~¨rÐ2Ó3ð ñ ð (ô —‘˜“ˆð Ñ Ü�E“
˜a’Ø—‘ 5§;¡;¨q¡>°5·;±;¸q±>ÀAÑ3EÐ"FÒFñ å:ð "×)Ñ)¨'Ó2�ô #+×"6Ñ"6°vÓ">‘�˜ñ
 *7Ø˜7Ÿ?™?¨5¯;©;Ó7ó*Ñ&��v˜wð $ FÑ+�à˜F‘^ GÑ,‘ô —X‘Xœs 8›}¨aÐ0Ó1�Ø(0×(8Ñ(8¸Ó(A��5—=‘= Ó$Ñ%ô  &Ÿ~™~×<Ñ<ÀÈ%Ð<ÓPˆF�8ÒØÐ!å7ä—‘œ3˜x›=¨!Ð,Ó-ˆBØ$,×$4Ñ$4°WÓ$=ˆBˆu�}‰}˜RÓ Ñ!Ù-°Ô4ˆF�8Ñàˆˆw‰à!€Fˆ:Ñð �ÑÜ /°¸Ñ0@Ó Aˆˆ}ÑØ�8ÑÜ"1°(¸8Ñ2DÓ"EˆˆÑð —‘˜V RÓ(×,Ñ,¨V°TÓ:€IØÐàˆÜ�i¤Ô&ðÜŸ™¨°9Ñ)=¸yÈÑ?SÐ(TÓU‘ô ˜	¤2§:¡:Ô.ä�9—?‘?Ó# qÒ(¨Y¯_©_¸QÑ-?À1Ò-DØ!‘ô 3°9Ó=�àÐÝ:à�M‰M™-¨¨v°jÑ/AÓBÔCØ€Mùò_ $Rùò Høô ò ÚðûôX œHÐ%ò 	ò ð	ûô2 #¤HÐ-ò âðûôT !ò Ü—	‘	Ø=¸i¿n¹nÓ>NÐ=OÐPØ!÷ðús`   ¦S7Á(T Á;S<Â#T Ç T ÈA7T'Ñ"T= Ó<T Ô	TÔTÔT$Ô#T$Ô'T:Ô9T:Ô=1U1Õ0U1c                 ó–   — g d¢}|D �cg c]  }|| d   v sŒ| d   |   ‘Œ }}t        |«      dk\  rt        j                  |«      S yc c}w )aT  
    Given an element, try to extract RGBA color from
    properties and return them as an (n,3|4) array.

    Parameters
    -------------
    element : dict
      Containing color keys

    Returns
    ------------
    colors : (n, 3) or (n, 4) float
      Colors extracted from the element
    signal : float
      Estimate of range
    )ÚredÚgreenÚblueÚalpharÓ   rQ   r€   N)rœ   rh   r£   )rÒ   r  r  Úcandidate_colorss       r2   r  r  ì  sZ   € ò" -€DÙ48ÓW±D¨q¸AÀÈÑAVÒ<V˜ ™¨Ó*°DÐÐWÜ
ÐÓ Ò!Ü�‰Ð/Ó0Ð0Øùò Xs
   ‰A–
Ac                 óº  — | j                  «       D �ci c]  }|g “Œ }}|D ]v  }d}| j                  «       D ]_  \  }}d}d|v r'|j                  d«      d   }t        ||   «      }|dz  }||z   }	||   j	                  |||	 j                  |«      «       |	}Œa Œx |j                  «       D ��
ci c]  \  }}
|t        j                  |
d¬«      “Œ }}}
|j                  |j                  «       D ��
ci c]M  \  }}
t        |
j                  «      dk(  r0||
j                  «       j                  ||   d   j                  «      “ŒO c}
}«       |S c c}w c c}
}w c c}
}w )	aW  
    Load elements which include lists of different lengths
    based on the element's property-definitions.

    Parameters
    ------------
    properties : dict
      Property definitions encoded in a dict where the property name is the key
      and the property data type the value.
    data : array
      Data rows for this element.
    r   r.   ú$LISTú($LIST,)r‰   ÚobjectrŠ   r   )r  rW   rÞ   r   r]   Úastyperh   rŸ   r©   rœ   r\   ÚsqueezerX   )rÓ   rQ   rÉ   ÚedataÚrowÚstartr_   ÚdtrÃ   ÚendrÊ   r  s               r2   Ú_load_element_differentr%    sb  € ð 'ŸO™OÔ-Ó.Ñ-�qˆQ�‰UÐ-€EÐ.ÛˆØˆØ"×(Ñ(Ö*‰HˆD�"ØˆFØ˜"‰}Ø—X‘X˜jÓ)¨"Ñ-�ô ˜S ™Z›�à˜‘
�Ø˜&‘.ˆCØ�$‰K×Ñ˜s 5¨˜~×4Ñ4°RÓ8Ô9à‰Eñ +ð ð$ ;@¿+¹+¼-ÔH¹-±$°!°Qˆq”"—(‘(˜1 HÔ-Ñ-¸-€GÑHà‡N�Nð  Ÿ™œô	
á'‘��1Ü�1—7‘7‹|˜qÒ ð ˆq�y‰y‹{×!Ñ! %¨¡(¨1¡+×"3Ñ"3Ó4Ñ4Ø'ò	
ôð €Nùò; /ùó& Iùó	
s   “
EÂ-"EÃ0AE
c                 ó^  — |d   }i }d}| j                  «       D ]�  \  }}|t        |«      k\  r |S d|v rQ|j                  d«      d   }t        ||   «      }|dd…|dz   |dz   |z   …f   j	                  |«      ||<   ||dz   z  }Œl|dd…||dz   …f   j	                  |«      ||<   |dz  }Œ’ |S )aÆ  
    Load element data with lists of a single length
    based on the element's property-definitions.

    Parameters
    ------------
    properties : dict
      Property definitions encoded in a dict where
      the property name is the key and the property
      data type the value.
    data : array
      Data rows for this element, if the data contains
      list-properties all lists belonging to one property
      must have the same length.
    r   r  r  r‰   Nr.   )rW   rœ   rÞ   r   r  )	rÓ   rQ   ÚfirstÚcolumnsÚcurrentr_   r#  rX   rÃ   s	            r2   Ú_load_element_singler*  1  sç   € ð" �‰G€EØ€GØ€GØ×$Ñ$Ö&‰ˆˆbð ”c˜%“jÒ Øð €Nð �b‰=Ø—H‘H˜ZÓ(¨Ñ,ˆEô ˜˜w™Ó(ˆFØ ¢ G¨a¡K°'¸A±+ÀÑ2FÐ$FÐ!FÑG×NÑNÈuÓUˆG�D‰Mà�v ‘zÑ!‰Gà ¢ G¨g¸©kÐ$9Ð!9Ñ:×AÑAÀ"ÓEˆG�D‰MØ�q‰L‰Gð! 'ð$ €Nr4   c                 ó8  — t        |j                  «       j                  d«      «      }t         j                  |«      }|D �cg c]  }t	        j
                  |d¬«      ‘Œ }}d}| j                  «       D ]Ž  \  }}d|vs|d   dk(  rŒ||||d   z    }	||d   z  }	 t	        j                  |	«      }	d}
t        d„ |d	   j                  «       D «       «      }|
r|d
k  rt        |d	   |	«      }nt        |d	   |	«      }|| |   d<   Œ� yc c}w # t        $ r d}
Y Œfw xY w)aX  
    Load data from an ASCII PLY file into an existing elements data structure.

    Parameters
    ------------
    elements : OrderedDict
      Populated from the file header, data will
      be added in-place to this object
    file_obj : file-like-object
      Current position at the start
      of the data section (past the header).
    r–   rc   )Úsepr   rÃ   TFc              3   ó*   K  — | ]  }d |v sŒd–— Œ y­w)r  r.   N© )Ú.0r#  s     r2   Ú	<genexpr>z_ply_ascii.<locals>.<genexpr>�  s   è ø€ ÐTÑ%B˜rÀgÐQSÂmœÑ%Bùs   ‚	ŒrÓ   r.   rQ   N)r0   ÚreadrÚ   Ú
splitlinesrh   Ú
fromstringrW   r¥   rn   Úsumrm   r*  r%  )r=   rK   ÚtextÚlinesr  rŸ   Úrow_posÚkeyrm   rQ   Úcol_count_equalÚ
list_countÚelement_datas                r2   r?   r?   Z  s3  € ô ˆx�}‰}‹×%Ñ% gÓ.Ó/€Dä�N‰N˜4Ó €Eá05Ó6±¨1ŒR�]‰]˜1 #Ö&°€EÐ6à€Gð  —~‘~Ö'‰ˆˆVà˜6Ñ! V¨HÑ%5¸Ò%:ØØ�W˜w¨°Ñ)9Ñ9Ð:ˆØ�6˜(Ñ#Ñ#ˆð	$Ü—9‘9˜T“?ˆDØ"ˆOô
 ÑT V¨LÑ%9×%@Ñ%@Ô%BÓTÓTˆ
Ù˜z¨Qšô 0°°|Ñ0DÀdÓK‰Lô
 3°6¸,Ñ3GÈÓNˆLà ,ˆ�‰�fÒñ7 (ùò 7øô  ò 	$Ø#ŠOð	$ús   ÁDÂDÄDÄDc                 ó”   — d„ }d„ }d„ } ||| «       t        j                  |«      } || «      }||k7  rt        d«      ‚ ||| «       y)ac  
    Load the data from a binary PLY file into the elements data structure.

    Parameters
    ------------
    elements : OrderedDict
      Populated from the file header.
      Object will be modified to add data by this function.
    file_obj : open file object
      With current position at the start
      of the data section (past the header)
    c                 ó  — | j                  «       }| j                  «       }g }|j                  «       D �]¦  \  }}|d   }d}|j                  «       D ]ø  \  }	}
g }d|
v rât        j                  |
j	                  d«      d   «      }t        |«      dk(  rd}nt        j                  |«      j                  }| j                  ||z   «       | j                  |j                  «      }t        |«      dk(  r|j                  |	«        nHt        j                  ||¬«      d   }||	   j                  dt        |«      «      ||	<   |||	   dz   z  }Œú t        «      dkD  r9|D ]  }|j                  |«       Œ t        |«      dk(  r|j                  |«       �Œ`t        j                  dj                  |j                  «       «      «      j                  }||d   |z  z  }�Œ© | j                  |«       |D ]  }|j                  |«       Œ y	)
a1  
        Given a set of elements populated from the header if there are any
        list properties seek in the file the length of the list.

        Note that if you have a list where each instance is different length
        (if for example you mixed triangles and quads) this won't work at all
        rÓ   r•   r  Ú,r   rŠ   z, rÃ   N)ÚtellrW   rh   rX   rÞ   rœ   ÚitemsizeÚseekr1  r]   Ú
frombufferÚreplacer0   Úpopr­   rm   )rK   r=   Úp_startÚ	p_currentÚelem_popÚelement_keyrÒ   ÚpropsÚ
prior_datarÉ   rX   Úprop_popr`   rÄ   ÚblobÚsizerD  r@  s                     r2   Úpopulate_listsizez&_ply_binary.<locals>.populate_listsizež  sÈ  € ð —-‘-“/ˆØ—M‘M“Oˆ	ØˆØ$,§N¡N×$4Ñ ˆK˜Ø˜LÑ)ˆEØˆJØ!ŸK™KžM‘��5Ø�Ø˜eÑ#ô #%§(¡(¨5¯;©;°sÓ+;¸AÑ+>Ó"?�KÜ˜:“¨!Ò+Ø!"™ä!#§¡¨*Ó!5×!>Ñ!>˜Ø—M‘M )¨fÑ"4Ô5Ø#Ÿ=™=¨×)=Ñ)=Ó>�DÜ˜4“y A’~à Ÿ™¨Ô*ÙÜŸ=™=¨°[ÔAÀ!ÑD�DØ$ Q™x×/Ñ/°¼¸T»ÓC�E˜!‘HØ˜e A™h¨™nÑ,‘
ð' *ô( �8‹}˜qÒ ã#�CØ—I‘I˜c•Nð $ô �u“: ’?Ø—O‘O KÔ0Ùä—x‘x §	¡	¨%¯,©,«.Ó 9Ó:×CÑCˆHà˜ Ñ*¨XÑ5Ñ5ŠIðG %5ðJ 	�‰�gÔãˆCØ�L‰L˜Õñ r4   c                 óz  — |j                  «       D ]x  }t        ||   d   j                  «       «      }t        j                  |«      }| j                  ||   d   |j                  z  «      }	 t        j                  ||¬«      ||   d<   Œz |S # t        $ r# t        j                  d|› �«       d||   d<   Y Œ¨w xY w)z�
        Given the data type and field information from the header,
        read the data and add it to a 'data' field in the element.
        rÓ   rÃ   rŠ   rQ   zPLY failed to populate: N)r  rÕ   rW   rh   rX   r1  r@  rB  rH   r   rI   )rK   r=   r8  rW   rX   rQ   s         r2   Úpopulate_dataz"_ply_binary.<locals>.populate_dataÓ  sµ   € ð
 —=‘=–?ˆCÜ˜ #™ |Ñ4×:Ñ:Ó<Ó=ˆEÜ—H‘H˜U“OˆEØ—=‘= ¨#¡¨xÑ!8¸5¿>¹>Ñ!IÓJˆDð-Ü(*¯©°dÀ%Ô(H�˜‘˜fÒ%ð #ð ˆøô !ò -Ü—‘Ð6°s°eÐ<Ô=Ø(,�˜‘˜fÓ%ð-ús   Á-BÂ)B:Â9B:c                 óÈ   — d}| j                  «       D ]L  }t        j                  dj                  |d   j                  «       «      «      }||d   |j                  z  z  }ŒN |S )zŒ
        Given an elements data structure populated from the header,
        calculate how long the file should be if it is intact.
        r   r>  rÓ   rÃ   )rm   rh   rX   r­   r@  )r=   rM  rÒ   rX   s       r2   Ú_elements_sizez#_ply_binary.<locals>._elements_sizeã  s^   € ð
 ˆØ—‘Ö(ˆGÜ—H‘H˜SŸX™X g¨lÑ&;×&BÑ&BÓ&DÓEÓFˆEØ�G˜HÑ%¨¯©Ñ6Ñ6‰Dð )ð ˆr4   zPLY is unexpected length!N)r	   Údistance_to_endrn   )r=   rK   rN  rP  rR  Ú	size_fileÚsize_elementss          r2   r@   r@   �  s^   € ò3òjò 	ñ �h Ô)ô ×$Ñ$ XÓ.€Iñ # 8Ó,€Mð �MÒ!ÜÐ4Ó5Ð5ñ �(˜HÕ%r4   c                 óÖ  — t        j                  d¬«      5 }|j                  t        | «      «       |j	                  «        t        j                  d¬«      5 }t        j                  t        dt        t        |«      «      d|j                  d|j                  g«       |j                  d«       |j                  «       }ddd«       ddd«       S # 1 sw Y   ŒxY w# 1 sw Y   S xY w)	a‹  
    Export a mesh using Google's Draco compressed format.

    Only works if draco_encoder is in your PATH:
    https://github.com/google/draco

    Parameters
    ----------
    mesh : Trimesh object
      Mesh to export
    bits : int
      Bits of quantization for position
      tol.merge=1e-8 is roughly 25 bits

    Returns
    ----------
    data : str or bytes
      DRC file bytes
    ú.ply©Úsuffixú.drcz-qpú-iú-or   N)ÚtempfileÚNamedTemporaryFileÚwriterÌ   ÚflushÚ
subprocessÚcheck_outputÚdraco_encoderr0   r   r_   rA  r1  )r²   ÚbitsÚtemp_plyÚencodedrQ   s        r2   Úexport_dracorg    s¶   € ô( 
×	$Ñ	$¨FÕ	3°xØ�‰”z $Ó'Ô(Ø�‰ÔÜ×(Ñ(°Õ7¸7Ü×#Ñ#ä!ØÜœ˜D›	“NØØ—M‘MØØ—L‘Lðô
ð �L‰L˜ŒOØ—<‘<“>ˆD÷ 8÷ 
4ð" €K÷ 8Ð7ú÷ 
4ð" €Kús%   —ACÁA(CÃ CÃC	ÃCÃC(c           	      ó®  — t        j                  d¬«      5 }|j                  | j                  «       «       |j	                  «        t        j                  d¬«      5 }t        j                  t        d|j                  d|j                  g«       |j                  d«       t        |«      }ddd«       ddd«       |S # 1 sw Y   ŒxY w# 1 sw Y   |S xY w)zé
    Load a mesh from Google's Draco format.

    Parameters
    ----------
    file_obj : file- like object
      Contains data

    Returns
    ----------
    kwargs : dict
      Keyword arguments to construct a Trimesh object
    rZ  rX  rW  r[  r\  r   N)r]  r^  r_  r1  r`  ra  rb  Údraco_decoderr_   rA  rR   )rK   rM   Útemp_drcre  s       r2   Ú
load_dracork  +  s£   € ô 
×	$Ñ	$¨FÕ	3°xØ�‰�x—}‘}“Ô'Ø�‰Ôä×(Ñ(°Õ7¸8Ü×#Ñ#Ü  h§m¡m°T¸8¿=¹=ÐIôð �M‰M˜!ÔÜ˜hÓ'ˆF÷ 8÷	 
4ð €M÷ 8Ð7ú÷	 
4ð €Mús%   —AC
ÁAB>Â,C
Â>C	ÃC
Ã
CrÎ   rc  ri  Údrc)NTNF)rt   NT)N)é   )0rÜ   ra  r]  Ústringr   Únumpyrh   Únumpy.lib.recfunctionsr   r   r•   r   r   r	   r
   Ú	constantsr   ré   r   Ú	resolversr   Útypedr   rß   r/   r3   Úboolr0   rR   ra   rf   rk   rp   rÌ   r>   rJ   r  r%  r*  r?   r@   rg  rk  Ú_ply_loadersÚ_ply_exportersÚwhichrc  ri  r.  r4   r2   Ú<module>rx     sN  ðÛ Û Û Ý ã ß Yç 0Ó 0Ý Ý (Ý  Ý ðØ
ˆDðàˆTðð ˆTðð ˆdð	ð
 
ˆ4ðð ˆDðð ˆTðð ˆTðð ˆTðð ˆDðð ˆTðð ˆdðð ˆdðð ˆdðð ˆTðð  ˆtð!ð" ˆtð#ð$ Øò'€ð0 Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
Ø
ñ€ò0ð" !%ØØ#Ø ñAà˜‰oðAð ðAð ˜‘*ð	Að
 óAòHò2ò4ò.Lð2 Ø!%Ø#ñ	_ð ˜$‘;ð_ð ó	_òDP*ófJòZò0*òZ&òR3-òlp&óf%òPð8 �xÐ €Ø˜Ð$€à�—
‘
˜?Ó+€Ø�—
‘
˜?Ó+€ØÐØ$€L�ÑØÐØ(€N�5Òð r4   