Ë
    :vžjlÔ  ã                   ód  — U d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ d dl	Z
ddlmZmZmZmZmZmZmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZ ddlmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& ddlm'Z' ddlm(Z(m)Z) ddl*m+Z+ ee!e   z  e,e-ef   z  ez  Z.ee/d<    G d„ de«      Z0d„ Z1dd„Z2dde0dede0fd„Z3y)é    N)Údeepcopy)Úsha256)Ú	TypeAliasé   )ÚcachingÚconvexÚgroupingÚinertiaÚtransformationsÚunitsÚutil)Úlog)Úexport)ÚGeometryÚ
Geometry3D)Ú
procrustes)
Ú	ArrayLikeÚFloatingÚHashableÚIntegerÚIterableÚNDArrayÚSequenceÚ
ViewerTypeÚfloat64Úint64)Úunique_nameé   )ÚcamerasÚlighting)Ú
SceneGraphÚGeometryInputc                   ó´  — e Zd ZdZ	 	 	 	 	 	 	 dNdedz  dededz  dedz  dej                  dz  de
ej                     dz  d	edz  fd
„Zd„ Z	 	 	 	 	 dOdededz  dedz  dedz  dedz  dedz  fd„Zdeez  e
z  ddfd„ZdPd„Z	 	 	 dQdedz  dedz  dedz  ddfd„Zdefd„Zedefd„«       Zedefd„«       Zej>                  deeee    f   fd„«       Z!ej>                  dee    dz  fd„«       Z"ej>                  dee    dz  fd„«       Z#ej>                  de$fd„«       Z%ej>                  dee    dz  fd „«       Z&ej>                  defd!„«       Z'ej>                  d"„ «       Z(d#„ Z)ej>                  de$fd$„«       Z*ej>                  de fd%„«       Z+ej>                  dee    fd&„«       Z,ej>                  d'„ «       Z-ej>                  deeef   fd(„«       Z.ej>                  defd)„«       Z/ej>                  de0e0e      fd*„«       Z1dRd+edd fd,„Z2	 dOdej                  fd-„Z3ed.„ «       Z4e4jj                  d/e6fd0„«       Z4de7ee    ee    ee8   f   fd1„Z9edej                  fd2„«       Z:e:jj                  dej                  dz  fd3„«       Z:edefd4„«       Z;ede0ej                     fd5„«       Z<e<jj                  de
ej                     fd6„«       Z<dPd7„Z=dSd8ede0e>   fd9„Z?dTd:„Z@de>fd;„ZAd<edd fd=„ZBej>                  d>„ «       ZCdUd?„ZDdVdeEfd@„ZFededz  fdA„«       ZGeGjj                  dBefdC„«       ZGdSdDedEedd fdF„ZHdUdPdG„ZIdHee6z  dd fdI„ZJdWdJ„ZK	 dVdKeLfdL„ZMdM„ ZNy)XÚScenezê
    A simple scene graph which can be rendered directly via
    pyglet/openGL or through other endpoints such as a
    raytracer. Meshes are added by name, which can then be
    moved by updating transform in the transform tree.
    NÚgeometryÚ
base_frameÚmetadataÚgraphÚcameraÚlightsÚcamera_transformc                 óx  — t        j                  «       | _        t        |¬«      | _        t        j                  | j                  ¬«      | _        |�| j                  |«       i | _
        t        |t        «      r| j                  j                  |«       |�|| _        |�|| _        |�|| _        |�|| _        yyy)aX  
        Create a new Scene object.

        Parameters
        -------------
        geometry : Trimesh, Path2D, Path3D PointCloud or list
          Geometry to initially add to the scene
        base_frame
          Name of base frame
        metadata
          Any metadata about the scene
        graph
          A passed transform graph to use
        camera : Camera or None
          A passed camera to use
        lights : [trimesh.scene.lighting.Light] or None
          A passed lights to use
        camera_transform
          Homogeneous (4, 4) camera transform in the base frame
        ©r&   )Úid_functionN)ÚcollectionsÚOrderedDictr%   r!   r(   r   ÚCacheÚ__hash__Ú_cacheÚadd_geometryr'   Ú
isinstanceÚdictÚupdater*   r)   r+   )Úselfr%   r&   r'   r(   r)   r*   r+   s           úd/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/trimesh/scene/scene.pyÚ__init__zScene.__init__,   s°   € ô> $×/Ñ/Ó1ˆŒô  ¨:Ô6ˆŒ
ô —m‘m°·±Ô>ˆŒàÐà×Ñ˜hÔ'ð ˆŒÜ�h¤Ô%Ø�M‰M× Ñ  Ô*àÐàˆDŒJàÐØ ˆDŒKØÐØ ˆDŒKØÐ+Ø(8�Õ%ð ,ð ó    c                 ó
  — | j                   j                  }| j                   j                  j                  |   D ]F  }t	        j
                  || j                   |   d   «      }| j                   j                  |||¬«       ŒH | S )zà
        Apply a transform to all children of the base frame
        without modifying any geometry.

        Parameters
        --------------
        transform : (4, 4)
          Homogeneous transformation matrix.
        r   ©Ú
frame_fromÚframe_toÚmatrix)r(   r&   Ú
transformsÚchildrenÚnpÚdotr7   )r8   Ú	transformÚbaseÚchildÚcombineds        r9   Úapply_transformzScene.apply_transformg   sp   € ð �z‰z×$Ñ$ˆØ—Z‘Z×*Ñ*×3Ñ3°DÔ9ˆEÜ—v‘v˜i¨¯©°EÑ):¸1Ñ)=Ó>ˆHØ�J‰J×Ñ¨¸ÀhÐÕOð :ð ˆr;   Ú	node_nameÚ	geom_nameÚparent_node_namerE   c                 óX  — |€yt        j                  |«      r%|D �cg c]  }| j                  ||||||¬«      ‘Œ c}S t        |t        «      r6|j                  «       D ��	ci c]  \  }}	|| j                  |	||¬«      “Œ c}	}S t        |t        «      rj| |z   }
| j                  j                  «        | j                  j                  |
j                  «       |
j                  j                  | j                  _        y|�|}nld|j                  v r|j                  d   }nN|j                  j                  �|j                  j                  }n!dt        t!        | j                  «      «      z   }t#        || j                  j%                  «       ¬«      }|| j                  |<   |€@| j                  j                  j&                  j%                  «       }t#        ||«      }||vsJ ‚|€t)        j*                  d«      }| j                  j                  ||||dd	i|¬
«       |S c c}w c c}	}w )aµ  
        Add a geometry to the scene.

        If the mesh has multiple transforms defined in its
        metadata, they will all be copied into the
        TransformForest of the current scene automatically.

        Parameters
        ----------
        geometry : Trimesh, Path2D, Path3D PointCloud or list
          Geometry to initially add to the scene
        node_name : None or str
          Name of the added node.
        geom_name : None or str
          Name of the added geometry.
        parent_node_name : None or str
          Name of the parent node in the graph.
        transform : None or (4, 4) float
          Transform that applies to the added node.
        metadata : None or dict
          Optional metadata for the node.

        Returns
        ----------
        node_name : str
          Name of single node in self.graph (passed in) or None if
          node was not added (eg. geometry was null or a Scene).
        N)r%   rJ   rK   rL   rE   r'   )r%   rK   r'   ÚnameÚ	geometry_©ÚstartÚcontainsé   ÚvisibleT)r?   r>   r@   r%   Úgeometry_flagsr'   )r   Úis_sequencer4   r5   r6   Úitemsr$   r%   Úclearr7   r(   rA   r'   ÚsourceÚ	file_nameÚstrÚlenr   ÚkeysÚ	node_datarC   Úeye)r8   r%   rJ   rK   rL   rE   r'   ÚvalueÚkÚvÚconcatrN   Úexistings                r9   r4   zScene.add_geometryw   s-  € ðL ÐØä×Ñ˜hÔ'ñ &ó
ñ &�Eð ×!Ñ!Ø"Ø'Ø'Ø%5Ø'Ø%ð "õ ð &ñ
ð 
ô ˜¤$Ô'ð %ŸN™NÔ,ôá,‘D�A�qð �4×$Ñ$¨a¸1ÀxÐ$ÓPÑPØ,òð ô
 ˜¤%Ô(à˜H‘_ˆFà�M‰M×ÑÔ!Ø�M‰M× Ñ  §¡Ô1à$*§L¡L×$;Ñ$;ˆD�J‰JÔ!Øð Ð à‰DØ�x×(Ñ(Ñ(à×$Ñ$ VÑ,‰DØ�_‰_×&Ñ&Ð2Ø—?‘?×,Ñ,‰Dð ¤¤S¨¯©Ó%7Ó!8Ñ8ˆDô  °·±×0BÑ0BÓ0DÔEˆà&ˆ�‰�dÑð Ðð —z‘z×,Ñ,×6Ñ6×;Ñ;Ó=ˆHô $ D¨(Ó3ˆIØ HÑ,Ð,Ð,àÐäŸ™˜q›	ˆIà�
‰
×ÑØØ'ØØØ% tÐ,Øð 	ô 	
ð ÐùòK
ùós   �H!Á!H&ÚnamesÚreturnc                 óÔ   — t        |t        «      r|g}t        |«      }| j                  j	                  |«       |D �cg c]  }| j
                  j                  |d«      ‘Œ  c} yc c}w )a  
        Delete one more multiple geometries from the scene and also
        remove any node in the transform graph which references it.

        Parameters
        --------------
        name : hashable
          Name that references self.geometry
        N)r5   r[   Úsetr(   Úremove_geometriesr%   Úpop)r8   re   rN   s      r9   Údelete_geometryzScene.delete_geometryé   sX   € ô �eœSÔ!Ø�GˆEÜ�E“
ˆð 	�
‰
×$Ñ$ UÔ+á38Ó9±5¨4ˆ�‰×	Ñ	˜4 Õ	&°5Ó9ùÒ9s   ¾#A%c                 ó˜   — ddl m} | j                  j                  «       D ]'  }t	        j
                  |d«      sŒ ||¬«      |_        Œ) y)zl
        Strip visuals from every Trimesh geometry
        and set them to an empty `ColorVisuals`.
        r   )ÚColorVisualsÚTrimesh)ÚmeshN)Úvisual.colorrm   r%   Úvaluesr   Úis_instance_namedÚvisual)r8   rm   r%   s      r9   Ústrip_visualszScene.strip_visualsý   s:   € õ
 	0àŸ™×,Ñ,Ö.ˆHÜ×%Ñ% h°	Õ:Ù".°HÔ"=�•ñ /r;   ÚpercentÚ
face_countÚ
aggressionc                 óÊ   — i }| j                   j                  «       D ])  \  }}t        |d«      sŒ|j                  |||¬«      ||<   Œ+ | j                   j	                  |«       y)a½  
        Apply in-place `mesh.simplify_quadric_decimation` to any meshes
        in the scene.

        Parameters
        -----------
        percent
          A number between 0.0 and 1.0 for how much
        face_count
          Target number of faces desired in the resulting mesh.
        aggression
          An integer between `0` and `10`, the scale being roughly
          `0` is "slow and good" and `10` being "fast and bad."

        Úsimplify_quadric_decimation)ru   rv   rw   N)r%   rW   Úhasattrry   r7   )r8   ru   rv   rw   Úupdatesra   rb   s          r9   ry   z!Scene.simplify_quadric_decimation  sc   € ð, ˆØ—M‘M×'Ñ'Ö)‰DˆAˆqÜ�qÐ7Õ8Ø×:Ñ:Ø#°
Àzð ;ó �˜’
ð *ð
 	�‰×Ñ˜WÕ%r;   c                 ó.  ‡— | j                   Št        | j                  j                  j	                  «       «      g}|j                  ˆfd„‰j                  «       D «       «       t        j                  dj                  |«      j                  d«      «      S )z•
        Return information about scene which is hashable.

        Returns
        ---------
        hashed
          String hashing scene.
        c              3   óV   •K  — | ]   }t        ‰|   j                  «       «      –— Œ" y ­w©N)Úhexr2   )Ú.0ra   r%   s     €r9   Ú	<genexpr>z!Scene.__hash__.<locals>.<genexpr>5  s$   øè ø€ ÐM¹_¸œ˜H Q™K×0Ñ0Ó2×3¹_ùs   ƒ&)Ú zutf-8)r%   r   r(   rA   r2   Úextendr]   r   Ú	hash_fastÚjoinÚencode)r8   Úhashabler%   s     @r9   r2   zScene.__hash__&  sm   ø€ ð —=‘=ˆô ˜Ÿ
™
×-Ñ-×6Ñ6Ó8Ó9Ð:ˆà�‰ÓM¸X¿]¹]¼_ÓMÔMÜ× Ñ  §¡¨Ó!2×!9Ñ!9¸'Ó!BÓCÐCr;   c                 ó2   — t        | j                  «      dk(  S )z”
        Does the scene have anything in it.

        Returns
        ----------
        is_empty
          True if nothing is in the scene
        r   )r\   r%   ©r8   s    r9   Úis_emptyzScene.is_empty8  s   € ô �4—=‘=Ó! QÑ&Ð&r;   c                 ó  — t        | j                  «      dk(  ry	 | j                  j                  D �ch c]  }| j                  |   d   ’Œ }}|t        | j                  j                  «       «      k(  S c c}w # t        $ r Y yw xY w)z«
        Is every geometry connected to the root node.

        Returns
        -----------
        is_valid : bool
          Does every geometry have a transform
        r   Tr   F)r\   r%   r(   Únodes_geometryÚBaseExceptionrh   r]   )r8   ÚiÚ
referenceds      r9   Úis_validzScene.is_validE  s�   € ô ˆt�}‰}Ó Ò"Øð	Ø48·J±J×4MÒ4MÓNÑ4M¨q˜$Ÿ*™* Q™-¨Ó*Ð4MˆJÐNð œS §¡×!3Ñ!3Ó!5Ó6Ñ6Ð6ùò OøÜò 	áð	ús"   ›A9 ³A4ÁA9 Á4A9 Á9	BÂBc                 óP  — i }| j                   j                  «       D ��ci c]B  \  }}|t        |d«      r$t        |j                  «      dkD  r|j                  n|j
                  “ŒD }}}|j                  |j                  «       D ��ci c]M  \  }}|�F|j                  d   dk(  r4|t        j                  |t        j                  t        |«      «      f«      “ŒO c}}«       | j                  j                  D ]Ÿ  }| j                  |   \  }}|j                  |«      }	|	€Œ)t        j                  |dd…dd…f   |	j                  «      }
t        j                   |
j#                  d¬«      |dd…df   z   |
j%                  d¬«      |dd…df   z   g«      ||<   Œ¡ |S c c}}w c c}}w )zè
        Get the post-transform AABB for each node
        which has geometry defined.

        Returns
        -----------
        corners
          Bounds for each node with vertices:
           {node_name : (2, 3) float}
        Úverticesr   Nr   r   é   ©Úaxis)r%   rW   rz   r\   r’   Úboundsr7   ÚshaperC   Úcolumn_stackÚzerosr(   rŒ   ÚgetrD   ÚTÚarrayÚminÚmax)r8   Úcornersra   Úmr’   rb   rJ   rE   Úgeometry_nameÚpointsrD   s              r9   Úbounds_cornerszScene.bounds_corners[  sœ  € ð ˆð Ÿ™×+Ñ+Ô-ô
á-‘��1ð œW Q¨
Ô3¼¸A¿J¹J»È!Ò8Kˆq�zŠzÐQR×QYÑQYÑYØ-ð 	ñ 
ð
 	�‰ð %ŸN™NÔ,ôá,‘D�A�qØ�= Q§W¡W¨Q¡Z°1¢_ð ”2—?‘? A¤r§x¡x´°A³Ó'7Ð#8Ó9Ñ9Ø,òô	
ð Ÿ™×2Ô2ˆIà'+§z¡z°)Ñ'<Ñ$ˆI�}à—\‘\ -Ó0ˆFàˆ~Øä—&‘&˜ 2 A 2 r¨ r 6Ñ*¨F¯H©HÓ5ˆCä!#§¡Ø—‘˜a�“ 9¨R¨a¨R°¨UÑ#3Ñ3°S·W±WÀ!°W³_ÀyÐQSÐRSÐQSÐUVÐQVÑGWÑ5WÐXó"ˆG�IÒð 3ð ˆùó9
ùós    AFÂAF"
c                 ó2  — | j                   }t        |«      dk(  ryt        j                  t	        | j                   j                  «       «      «      }t        j                  |j                  d¬«      |j                  d¬«      gt        j                  ¬«      S )zå
        Return the overall bounding box of the scene.

        Returns
        --------
        bounds : (2, 3) float or None
          Position of [min, max] bounding box
          Returns None if no valid bounds exist
        r   Nr”   ©Údtype)
r£   r\   rC   ÚvstackÚlistrq   rœ   r�   rž   r   )r8   r£   rŸ   s      r9   r–   zScene.boundsˆ  sq   € ð ×,Ñ,ˆÜˆ~Ó !Ò#Øä—)‘)œD ×!4Ñ!4×!;Ñ!;Ó!=Ó>Ó?ˆÜ�x‰x˜Ÿ™¨!˜Ó,¨g¯k©k¸q¨kÓ.AÐBÌ"Ï*É*ÔUÐUr;   c                 ól   — | j                   }|€yt        j                  |d¬«      j                  d«      S )zß
        Return the axis aligned box size of the current scene
        or None if the scene is empty.

        Returns
        ----------
        extents
          Bounding box sides length or None for empty scene.
        Nr   r”   éÿÿÿÿ)r–   rC   ÚdiffÚreshape)r8   r–   s     r9   ÚextentszScene.extentsš  s1   € ð —‘ˆØˆ>ØÜ�w‰w�v AÔ&×.Ñ.¨rÓ2Ð2r;   c                 ó^   — | j                   }|€yt        |dz  j                  «       dz  «      S )z¢
        The approximate scale of the mesh

        Returns
        -----------
        scale : float
          The mean of the bounding box edge lengths
        ç      ð?r   g      à?)r­   ÚfloatÚsum)r8   r­   s     r9   ÚscalezScene.scaleª  s2   € ð —,‘,ˆØˆ?ØÜ�g˜q‘j×%Ñ%Ó'¨3Ñ.Ó/Ð/r;   c                 óf   — | j                   }|€yt        j                  | j                   d¬«      }|S )z°
        Return the center of the bounding box for the scene.

        Returns
        --------
        centroid : (3) float
          Point for center of bounding box
        Nr   r”   )r–   rC   Úmean)r8   r–   Úcentroids      r9   rµ   zScene.centroid¹  s.   € ð —‘ˆØˆ>ØÜ—7‘7˜4Ÿ;™;¨QÔ/ˆØˆr;   c                 óR  — | j                   j                  «       D ��ci c]  \  }}t        |d«      r||j                  “Œ  }}}| j                   j                  «       D ��ci c]  \  }}t        |d«      sŒ||j                  “Œ! }}}| j
                  }|j                  D �cg c]  }||   ‘Œ	 }}t        j                  |D ��	cg c]9  \  }}	|	|v r0t        j                  |t        j                  ||	   d«      «      dd ‘Œ; c}	}t        j                  ¬«      }
t        j                  |D ��	cg c]
  \  }}	||	   ‘Œ c}	}t        j                  ¬«      }||j                  «       z  }|
|j                  d«      z  j                  d¬	«      S c c}}w c c}}w c c}w c c}	}w c c}	}w )
z»
        Find the center of mass for every instance in the scene.

        Returns
        ------------
        center_mass : (3,) float
          The center of mass of the scene
        Úcenter_massÚmassr   Nr“   r¥   )rª   r   r   r”   )r%   rW   rz   r·   r¸   r(   rŒ   rC   rœ   rD   Úappendr   r±   r¬   )r8   ra   r    r·   r¸   r(   ÚnÚinstanceÚmatÚgÚtransformedÚ_Úweightss                r9   r·   zScene.center_massÉ  s‰  € ð Ÿ™×+Ñ+Ô-ô
á-‘��1Ü�q˜-Ô(ð ˆq�}‰}ÑØ-ð 	ñ 
ð
 '+§m¡m×&9Ñ&9Ô&;ÔRÑ&;™d˜a ¼wÀqÈ&Õ?Q��1—6‘6‘	Ð&;ˆÑRð —
‘
ˆØ&+×&:Ò&:Ó;Ñ&: �E˜!“HÐ&:ˆÐ;ô —h‘hñ 'ôá&‘F�C˜Ø˜Ñ#ô —‘�sœBŸI™I k°!¡n°aÓ8Ó9¸"¸1Ò=Ø&òô
 —*‘*ô
ˆô —(‘(±Ô9±©¨¨1˜D ›G°Ò9ÄÇÁÔLˆØ�7—;‘;“=Ñ ˆØ˜gŸo™o¨gÓ6Ñ6×;Ñ;ÀÐ;ÓCÐCùó/
ùó
 Sùò <ùóùó :s#   ž#FÁ!FÁ6FÂ"FÃ>F
Ä.F#
c                 ój   — t        j                  | t        j                  | j                  «      ¬«      S )a  
        Return the moment of inertia of the current scene with
        respect to the center of mass of the current scene.

        Returns
        ------------
        inertia : (3, 3) float
          Inertia with respect to cartesian axis at `scene.center_mass`
        ©ÚscenerE   )r
   Úscene_inertiar   Útranslation_matrixr·   r‰   s    r9   Úmoment_inertiazScene.moment_inertiaí  s-   € ô ×$Ñ$Ø¤/×"DÑ"DÀT×EUÑEUÓ"Vô
ð 	
r;   c                 ó0   — t        j                  | |¬«      S )aM  
        Return the moment of inertia of the current scene relative
        to a transform from the base frame.

        Parameters
        transform : (4, 4) float
          Homogeneous transformation matrix.

        Returns
        -------------
        inertia : (3, 3) float
          Inertia tensor at requested frame.
        rÂ   )r
   rÄ   )r8   rE   s     r9   Úmoment_inertia_framezScene.moment_inertia_frameü  s   € ô ×$Ñ$¨4¸9ÔEÐEr;   c                 óð   ‡ ‡— ‰ j                   j                  «       D ��ci c]  \  }}t        |d«      sŒ||j                  “Œ! c}}Št	        ˆˆ fd„‰ j
                  j                  D «       d«      S c c}}w )zÀ
        What is the summed area of every geometry which
        has area.

        Returns
        ------------
        area : float
          Summed area of every instanced geometry
        Úareac              3   ób   •K  — | ]&  }‰j                  ‰j                  |   d    d«      –— Œ( y­w©r   ç        N©rš   r(   )r€   rº   Úareasr8   s     €€r9   r�   zScene.area.<locals>.<genexpr>  s,   øè ø€ ÐQÑ7P°!ˆU�Y‰Y�t—z‘z !‘} QÑ'¨×-Ñ7Pùó   ƒ,/rÍ   )r%   rW   rz   rÊ   r±   r(   rŒ   )r8   rº   r½   rÏ   s   `  @r9   rÊ   z
Scene.area  se   ù€ ð (,§}¡}×':Ñ':Ô'<ÔSÑ'<™t˜q !ÄÈÈ6Õ@R��A—F‘F‘Ð'<ÒSˆäÜQ°t·z±z×7PÒ7PÓQÐSVó
ð 	
ùó Tó
    A2µA2c                 óð   ‡ ‡— ‰ j                   j                  «       D ��ci c]  \  }}t        |d«      sŒ||j                  “Œ! c}}Št	        ˆ ˆfd„‰ j
                  j                  D «       d«      S c c}}w )zÅ
        What is the summed volume of every geometry which
        has volume

        Returns
        ------------
        volume : float
          Summed area of every instanced geometry
        rÊ   c              3   ób   •K  — | ]&  }‰j                  ‰j                  |   d    d«      –— Œ( y­wrÌ   rÎ   )r€   rº   r8   Úvolumes     €€r9   r�   zScene.volume.<locals>.<genexpr>-  s,   øè ø€ ÐRÑ8Q°1ˆV�Z‰Z˜Ÿ
™
 1™ aÑ(¨#×.Ñ8QùrÐ   rÍ   )r%   rW   rz   rÔ   r±   r(   rŒ   )r8   rº   r½   rÔ   s   `  @r9   rÔ   zScene.volume  se   ù€ ð +/¯-©-×*=Ñ*=Ô*?ÔVÑ*?¡$ ! QÄ7È1ÈfÕCU�!�Q—X‘X‘+Ð*?ÒVˆäÜR¸¿
¹
×8QÒ8QÓRÐTWó
ð 	
ùó WrÑ   c           	      ó2  — g }g }| j                   j                  D ]µ  }| j                   |   \  }}| j                  |   }t        |d«      sŒ1|j	                  t        j                  |j                  j                  «       j                  d«      |¬«      «       |j	                  t        j                  |t        |j                  «      «      «       Œ· t        j                  |«      | j                  d<   t        j                  |«      j                  d«      S )zÀ
        Return a correctly transformed polygon soup of the
        current scene.

        Returns
        ----------
        triangles : (n, 3, 3) float
          Triangles in space
        Ú	triangles)rª   r“   )r@   Útriangles_node)rª   r“   r“   )r(   rŒ   r%   rz   r¹   r   Útransform_pointsrÖ   Úcopyr¬   rC   Útiler\   Úhstackr3   r§   )r8   rÖ   r×   rJ   rE   r¡   r%   s          r9   rÖ   zScene.triangles0  sç   € ð ˆ	ØˆØŸ™×2Ô2ˆIà'+§z¡z°)Ñ'<Ñ$ˆI�}ð —}‘} ]Ñ3ˆHÜ˜8 [Ô1Øà×ÑÜ×0Ñ0Ø×&Ñ&×+Ñ+Ó-×5Ñ5°gÓ>Àyôôð ×!Ñ!¤"§'¡'¨)´S¸×9KÑ9KÓ5LÓ"MÕNð 3ô" )+¯	©	°.Ó(Aˆ�‰Ð$Ñ%Ü�y‰y˜Ó#×+Ñ+¨JÓ7Ð7r;   c                 ó8   — | j                   }| j                  d   S )zÂ
        Which node of self.graph does each triangle come from.

        Returns
        ---------
        triangles_index : (len(self.triangles),)
          Node name for each triangle
        r×   )rÖ   r3   )r8   Úpopulates     r9   r×   zScene.triangles_nodeQ  s   € ð —>‘>ˆØ�{‰{Ð+Ñ,Ð,r;   c                 ó~   — | j                   j                  «       D ��ci c]  \  }}|j                  |“Œ c}}S c c}}w )z¡
        Look up geometries by identifier hash.

        Returns
        ---------
        identifiers
          {Identifier hash: key in self.geometry}
        )r%   rW   Úidentifier_hash)r8   rN   ro   s      r9   Úgeometry_identifierszScene.geometry_identifiers^  s;   € ð >B¿]¹]×=PÑ=PÔ=RÔSÑ=R©z¨t°T�×$Ñ$ dÑ*Ð=RÒSÐSùÓSs   ž9c                 óî   — dj                  d„ | j                  j                  «       D «       «      t        t	        | j
                  «      «      z   }t        |j                  «       «      j                  «       S )z8
        Get a unique identifier for the scene.
        r‚   c              3   ó4   K  — | ]  }|j                   –— Œ y ­wr~   )rß   ©r€   r½   s     r9   r�   z(Scene.identifier_hash.<locals>.<genexpr>o  s   è ø€ ÐIÑ2H¨Q�q×(Õ(Ñ2Hùs   ‚)	r…   r%   rq   r[   Úhashr(   r   r†   Ú	hexdigest)r8   Údumps     r9   rß   zScene.identifier_hashj  sZ   € ð
 �w‰wÑI°$·-±-×2FÑ2FÔ2HÓIÓIÌCÜ�—‘ÓóM
ñ 
ˆô �d—k‘k“mÓ$×.Ñ.Ó0Ð0r;   c           	      ó:  — t        | j                  «      dk(  rg S | j                  j                  «       D ��ci c](  \  }}t        |d«      r|t	        |j
                  d«      “Œ* }}}| j                  }|j                  D �ci c]  }||j                  ||   d   «      “Œ }}t        j                  t        «      }|j                  «       D ��cg c]  \  }}|�||   j                  |«      ‘Œ c}} t        |j                  «       «      S c c}}w c c}w c c}}w )a@  
        Return a sequence of node keys of identical meshes.

        Will include meshes with different geometry but identical
        spatial hashes as well as meshes repeated by self.nodes.

        Returns
        -----------
        duplicates
          Keys of self.graph that represent identical geometry
        r   rß   é   r   )r\   r%   rW   rz   Úintrß   r(   rŒ   rš   r/   Údefaultdictr¨   r¹   rq   )	r8   ra   r    Úhashesr(   ÚnodeÚ	node_hashÚ
duplicatesÚhasheds	            r9   Úduplicate_nodeszScene.duplicate_nodest  s!  € ô ˆt�}‰}Ó Ò"ØˆIð
 Ÿ™×+Ñ+Ô-ô
á-‘��1Ü�qÐ+Ô,ð Œs�1×$Ñ$ bÓ)Ñ)Ø-ð 	ñ 
ð —
‘
ˆð CH×BVÒBVÓWÑBV¸$�T˜6Ÿ:™: e¨D¡k°!¡nÓ5Ñ5ÐBVˆ	ÐWô !×,Ñ,¬TÓ2ˆ
ð
 !*§¡Ô 1ô	
á 1‘��fØÐ!ð �vÑ×%Ñ% dÕ+Ø 1ó	
ô �J×%Ñ%Ó'Ó(Ð(ùó/
ùò Xùó	
s   ¸-DÂDÃ DÚcost_thresholdc                 ó   — t        | |¬«      S )a®  
        If a scene has been "baked" with meshes it means that
        the duplicate nodes have *corresponding vertices* but are
        rigidly transformed to different places.

        This means the problem of finding ab instance transform can
        use the `procrustes` analysis which is *very* fast relative
        to more complicated registration problems that require ICP
        and nearest-point-on-surface calculations.

        TODO : construct a parent non-geometry node for containing every group.

        Parameters
        ----------
        scene
        The scene to handle.
        cost_threshold
        The maximum value for `procrustes` cost which is "squared mean
        vertex distance between pair". If the fit is above this value
        the instance will be left even if it is a duplicate.

        Returns
        ---------
        dedupe
        A copy of the scene de-duplicated as much as possible.
        )rñ   )Úreconstruct_instances)r8   rñ   s     r9   ró   zScene.reconstruct_instancesŸ  s   € ô6 % T¸.ÔIÐIr;   c                 óÈ  — |€t        j                  ddg«      }t        | j                  «      dk(  r]t	        j
                  |¬«      | _        t        j                  d«      | j                  | j                  j                  <   | j                  S |€t        j                  d«      }t        j                  |Ž }t	        j                  | j                  ||||¬«      }t        | d«      r1| j                  �%|| j                  _        |�.|| j                  _        nt	        j
                  ||¬	«      | _        || j                  | j                  j                  <   | j                  S )
a  
        Create a camera object for self.camera, and add
        a transform to self.graph for it.

        If arguments are not passed sane defaults will be figured
        out which show the mesh roughly centered.

        Parameters
        -----------
        angles : (3,) float
          Initial euler angles in radians
        distance : float
          Distance from centroid
        center : (3,) float
          Point camera should be center on
        camera : Camera object
          Object that stores camera parameters
        é<   é-   r   )ÚfovrS   r“   )r÷   ÚrotationÚdistanceÚcenterÚ_camera)r÷   Ú
resolution)rC   rœ   r\   r%   r   ÚCamerarû   r_   r(   rN   r™   r   Úeuler_matrixÚlook_atr–   rz   r÷   rü   )r8   Úanglesrù   rú   rü   r÷   rø   rE   s           r9   Ú
set_camerazScene.set_camera¼  s  € ð, ˆ;Ü—(‘(˜B ˜8Ó$ˆCô ˆt�}‰}Ó Ò"Ü"Ÿ>™>¨cÔ2ˆDŒLÜ,.¯F©F°1«IˆD�J‰J�t—|‘|×(Ñ(Ñ)Ø—<‘<Ðàˆ>Ü—X‘X˜a“[ˆFä"×/Ñ/°Ð8ˆÜ—O‘OØ�K‰K˜S¨8¸hÈvô
ˆ	ô �4˜Ô#¨¯©Ð(@Ø"ˆD�L‰LÔØÐ%Ø*4�—‘Õ'ô #Ÿ>™>¨c¸jÔIˆDŒLà(1ˆ�
‰
�4—<‘<×$Ñ$Ñ%à�|‰|Ðr;   c                 óN   — | j                   | j                  j                     d   S )z¯
        Get camera transform in the base frame.

        Returns
        -------
        camera_transform : (4, 4) float
          Camera transform in the base frame
        r   ©r(   r)   rN   r‰   s    r9   r+   zScene.camera_transformï  s"   € ð �z‰z˜$Ÿ+™+×*Ñ*Ñ+¨AÑ.Ð.r;   r@   c                 óJ   — || j                   | j                  j                  <   y)z¸
        Set the camera transform in the base frame

        Parameters
        ----------
        camera_transform : (4, 4) float
          Camera transform in the base frame
        Nr  )r8   r@   s     r9   r+   zScene.camera_transformû  s   € ð (.ˆ�
‰
�4—;‘;×#Ñ#Ò$r;   c                 óä   — | j                   j                  «       \  }}| j                  }t        j                  ||d¬«      }t        j                  |«      t        j                  |«      z  }|||fS )a²  
        Calculate the trimesh.scene.Camera origin and ray
        direction vectors. Returns one ray per pixel as set
        in camera.resolution

        Returns
        --------------
        origin: (n, 3) float
          Ray origins in space
        vectors: (n, 3) float
          Ray direction unit vectors in world coordinates
        pixels : (n, 2) int
          Which pixel does each ray correspond to in an image
        F)Ú	translate)r)   Úto_raysr+   r   rØ   rC   Ú	ones_likeÚtranslation_from_matrix)r8   ÚvectorsÚpixelsrE   Úoriginss        r9   Úcamera_rayszScene.camera_rays  sl   € ð  Ÿ+™+×-Ñ-Ó/‰ˆ�à×)Ñ)ˆ	ä!×2Ñ2°7¸IÐQVÔWˆä—,‘,˜wÓ'¬/×*QÑ*QØó+
ñ 
ˆð ˜ Ð'Ð'r;   c                 ón   — | j                   s| j                  «       S | j                  €J ‚| j                  S )zð
        Get the single camera for the scene. If not manually
        set one will abe automatically generated.

        Returns
        ----------
        camera : trimesh.scene.Camera
          Camera object defined for the scene
        )Ú
has_camerar  rû   r‰   s    r9   r)   zScene.camera"  s2   € ð �Šà—?‘?Ó$Ð$Ø�|‰|Ð'Ð'Ð'à�|‰|Ðr;   c                 ó   — |€y|| _         y)z¨
        Set a camera object for the Scene.

        Parameters
        -----------
        camera : trimesh.scene.Camera
          Camera object for the scene
        N)rû   )r8   r)   s     r9   r)   zScene.camera5  s   € ð ˆ>ØØˆ�r;   c                 ó:   — t        | d«      xr | j                  d uS )Nrû   )rz   rû   r‰   s    r9   r  zScene.has_cameraC  s   € ä�t˜YÓ'ÒD¨D¯L©LÀÐ,DÐDr;   c                 óâ   — t        | d«      r| j                  €Lt        j                  | «      \  }}t	        ||«      D ]  \  }}|| j
                  |j                  <   Œ  || _        | j                  S )zí
        Get a list of the lights in the scene. If nothing is
        set it will generate some automatically.

        Returns
        -------------
        lights : [trimesh.scene.lighting.Light]
          Lights in the scene.
        Ú_lights)rz   r  r    Ú	autolightÚzipr(   rN   )r8   r*   rA   ÚLr›   s        r9   r*   zScene.lightsG  sf   € ô �t˜YÔ'¨4¯<©<Ð+?ä!)×!3Ñ!3°DÓ!9ÑˆF�Jä˜F JÖ/‘��1Ø%&�—
‘
˜1Ÿ6™6Ò"ð 0ð "ˆDŒLØ�|‰|Ðr;   c                 ó   — || _         y)z·
        Assign a list of light objects to the scene

        Parameters
        --------------
        lights : [trimesh.scene.lighting.Light]
          Lights in the scene.
        N)r  )r8   r*   s     r9   r*   zScene.lights\  s   € ð ˆ�r;   c                 óz  — | j                   s t        j                  | j                  d«      ryt        j                  d«      }| j                   |dd…df<   t        | j                  j                  «      dz   }| j                  j                  || j                  j                  |¬«       || j                  _        y)zÂ
        Move the current scene so that the AABB of the whole
        scene is centered at the origin.

        Does this by changing the base frame to a new, offset
        base frame.
        rÍ   NrS   r“   Ú_Ir=   )	rŠ   rC   Úallcloserµ   r_   r[   r(   r&   r7   )r8   r@   Únew_bases      r9   ÚrezerozScene.rezeroh  s–   € ð �=Š=œBŸK™K¨¯©°sÔ;àô —‘˜“ˆØŸ™˜ˆˆr�ˆr�1ˆu‰ô �t—z‘z×,Ñ,Ó-°Ñ4ˆØ�
‰
×ÑØ¨$¯*©*×*?Ñ*?Èð 	ô 	
ð !)ˆ�
‰
Õr;   Úconcatenatec                 óV  — g }| j                   j                  D ]Ú  }| j                   |   \  }}| j                  |   j                  «       }t	        |d«      r]t        j                  |t
        j                  d¬«      }d|dd…dd…f<   |j                  «       s|j                  «       }n|dd…dd…f   }|j                  |«       ||j                  d<   ||j                  d	<   |j                  |«       ŒÜ |r1t        j                  d
t        d¬«       t        j                   |«      S |S )a­  
        Get a list of every geometry moved to its instance position,
        i.e. freezing or "baking" transforms.

        Parameters
        ------------
        concatenate
          KWARG IS DEPRECATED FOR REMOVAL APRIL 2025
          Concatenate results into single geometry.
          This keyword argument will make the type hint incorrect and
          you should replace `Scene.dump(concatenate=True)` with:
            - `Scene.to_geometry()` for a Trimesh, Path2D or Path3D
            - `Scene.to_mesh()` for only `Trimesh` components.

        Returns
        ----------
        dumped
          Copies of `Scene.geometry` transformed to their instance position.
        Úto_3Dg:Œ0âŽyE>)ÚatolTNr   r“   rN   rì   zd`Scene.dump(concatenate=True)` DEPRECATED FOR REMOVAL APRIL 2025: replace with `Scene.to_geometry()`)ÚcategoryÚ
stacklevel)r(   rŒ   r%   rÙ   rz   r   ÚiscloseÚ	_IDENTITYÚallr  rI   r'   r¹   ÚwarningsÚwarnÚDeprecationWarningr  )r8   r  ÚresultrJ   rE   r¡   ÚcurrentÚchecks           r9   ræ   z
Scene.dump  s  € ð* ˆØŸ™×2Ô2ˆIØ'+§z¡z°)Ñ'<Ñ$ˆI�}à—m‘m MÑ2×7Ñ7Ó9ˆGô �w Ô(äŸ™ Y´·±ÀTÔJ�Ø $��b�q�b˜"˜1˜"�f‘Ø—y‘y”{à%Ÿm™m›o‘Gð !*¨"¨1¨"¨b¨q¨b¨&Ñ 1�Ið ×#Ñ# IÔ.Ø'4ˆG×Ñ˜VÑ$Ø'0ˆG×Ñ˜VÑ$ð �M‰M˜'Õ"ð/ 3ñ2 Ü�M‰MØvÜ+Øõô ×#Ñ# FÓ+Ð+àˆr;   c           	      ó”   — ddl m} t        j                  | j	                  «       D �cg c]  }t        ||«      sŒ|‘Œ c}«      S c c}w )a>  
        Concatenate every mesh instances in the scene into a single mesh,
        applying transforms and "baking" the result. Will drop any geometry
        in the scene that is not a `Trimesh` object.

        Returns
        ----------
        mesh
          All meshes in the scene concatenated into one.
        r   )rn   )rF   rn   r   r  ræ   r5   )r8   rn   Úds      r9   Úto_meshzScene.to_mesh¹  s;   € õ 	#ô ×Ñ¨D¯I©I¬KÓ R©K q¼:ÀaÈÕ;Q¢¨KÑ RÓSÐSùÒ Rs
   ¨AºAc                 óH   — t        j                  | j                  «       «      S )aM  
        Concatenate geometry in the scene into a single like-typed geometry,
        applying the transforms and "baking" the result. May drop geometry
        if the scene has mixed geometry.

        Returns
        ---------
        concat
          Either a Trimesh, Path2D, or Path3D depending on what is in the scene.
        )r   r  ræ   r‰   s    r9   Úto_geometryzScene.to_geometryÉ  s   € ô ×Ñ §	¡	£Ó,Ð,r;   rì   c                 ó„  — | j                   }|j                  j                  |«      }|j                  «       D �cg c]  }|d   |v sŒ|‘Œ }}t	        |¬«      }|j                  |«       |D �ch c]  }d|d   v sŒ|d   d   ’Œ }}|D �ci c]  }|| j                  |   “Œ }}t        ||¬«      }	|	S c c}w c c}w c c}w )a	  
        Get part of a scene that succeeds a specified node.

        Parameters
        ------------
        node
          Hashable key in `scene.graph`

        Returns
        -----------
        subscene
          Partial scene generated from current.
        r   r-   r%   r   ©r%   r(   )r(   rA   Ú
successorsÚto_edgelistr!   Úfrom_edgelistr%   r$   )
r8   rì   r(   ÚnodesÚeÚedgesÚgeometry_namesra   r%   r)  s
             r9   ÚsubscenezScene.subscene×  sÐ   € ð  —
‘
ˆØ× Ñ ×+Ñ+¨DÓ1ˆà!×-Ñ-Ô/ÓAÑ/�q°1°Q±4¸5²=’Ð/ˆÐAô  dÔ+ˆØ×Ñ˜EÔ"á49ÓP±E¨q¸ZÈ1ÈQÉ4Ò=O˜!˜A™$˜zÓ*°EˆÐPÙ1?Ó@±¨A�A�t—}‘} QÑ'Ñ'°ˆÐ@Ü °Ô6ˆØˆùò Bùò QùÚ@s   ºB3ÁB3Á.B8Á;
B8ÂB=c                 ó¬   — t        j                  | j                  «       D �cg c]  }|j                  ‘Œ c}«      }t	        j
                  |«      S c c}w )z¾
        The convex hull of the whole scene.

        Returns
        ---------
        hull : trimesh.Trimesh
          Trimesh object which is a convex hull of all meshes in scene
        )r   Úvstack_emptyræ   r’   r   Úconvex_hull)r8   r    r¢   s      r9   r=  zScene.convex_hullõ  sD   € ô ×"Ñ"¸¿	¹	¼Ó#D¹°1 A§J£J¸Ñ#DÓEˆÜ×!Ñ! &Ó)Ð)ùò $Es   ¢Ac                 ó4   — t        j                  d| ||dœ|¤ŽS )a  
        Export a snapshot of the current scene.

        Parameters
        ----------
        file_obj : str, file-like, or None
          File object to export to
        file_type : str or None
          What encoding to use for meshes
          IE: dict, dict64, stl

        Returns
        ----------
        export : bytes
          Only returned if file_obj is None
        )rÃ   Úfile_objÚ	file_type© )r   Úexport_scene)r8   r?  r@  Úkwargss       r9   r   zScene.export  s+   € ô" ×"Ñ"ð 
Ø °Yñ
ØBHñ
ð 	
r;   c                 ó(   — ddl m}  |d| |dddœ|¤ŽS )a1  
        Get a PNG image of a scene.

        Parameters
        -----------
        resolution : (2,) int
          Resolution to render image
        **kwargs
          Passed to SceneViewer constructor

        Returns
        -----------
        png : bytes
          Render of scene as a PNG
        r   )Úrender_sceneF)rÃ   rü   Ú
fullscreenÚ	resizablerA  )Úviewer.windowedrE  )r8   rü   rC  rE  s       r9   Ú
save_imagezScene.save_image  s*   € õ  	3áð 
Ø :¸%È5ñ
ØTZñ
ð 	
r;   c                 óú   — | j                   j                  «       D �ch c]  }|j                  ’Œ }}t        |«      dk(  r|j	                  «       S t        |«      dkD  rt        j                  d|› d�«       yc c}w )a  
        Get the units for every model in the scene. If the scene has
        mixed units or no units this will return None.

        Returns
        -----------
        units
          Units for every model in the scene or None
          if there are no units or mixed units
        r   zMixed units `z` returning NoneN)r%   rq   r   r\   rj   r   Úwarning)r8   rŽ   rd   s      r9   r   zScene.units-  sm   € ð &*§]¡]×%9Ñ%9Ô%;Ó<Ñ%; �A—G“GÐ%;ˆÐ<Üˆx‹=˜AÒØ—<‘<“>Ð!Ü�‹]˜QÒÜ�K‰K˜-¨ zÐ1AÐBÔCØùò =s   �A8r`   c                 óŒ   — |j                  «       j                  «       }| j                  j                  «       D ]	  }||_        Œ y)zè
        Set the units for every model in the scene without
        converting any units just setting the tag.

        Parameters
        ------------
        value : str
          Value to set every geometry unit value to
        N)ÚstripÚlowerr%   rq   r   )r8   r`   r    s      r9   r   zScene.unitsA  s6   € ð —‘“×#Ñ#Ó%ˆØ—‘×%Ñ%Ö'ˆAØˆA�Gñ (r;   ÚdesiredÚguessc                 ó   — t        | j                  «      dk(  r| j                  «       S | j                  }|€t        j                  | |¬«      }t        j
                  ||¬«      }| j                  |¬«      }||_        |S )a%  
        If geometry has units defined convert them to new units.

        Returns a new scene with geometries and transforms scaled.

        Parameters
        ----------
        desired : str
          Desired final unit system: 'inches', 'mm', etc.
        guess : bool
          Is the converter allowed to guess scale when models
          don't have it specified in their metadata.

        Returns
        ----------
        scaled : trimesh.Scene
          Copy of scene with scaling applied and units set
          for every model
        r   )rP  )r*  rO  )r²   )r\   r%   rÙ   r   Úunits_from_metadataÚunit_conversionÚscaled)r8   rO  rP  r*  r²   r)  s         r9   Úconvert_unitszScene.convert_unitsP  sw   € ô* ˆt�}‰}Ó Ò"Ø—9‘9“;Ðà—*‘*ˆØˆ?ô ×/Ñ/°¸EÔBˆGô ×%Ñ%¨g¸wÔGˆð —‘ 5�Ó)ˆð ˆŒàˆr;   c                 óÐ  — |€| j                   }|€| j                  dz  }t        j                  |t        j                  ¬«      }t        j                  |t        j                  ¬«      }| j
                  j                  D ]ä  }| j
                  |   \  }}| j                  |   j                   }t        j                  |t        j                  |d«      «      dd }|j                  dk(  r	||z
  |z  }nBt        j                  |«      dk(  rt        j                  |||z
  «      }||z  }nt        d«      ‚|j                  «       }	|	dd…dfxx   |z  cc<   |	| j
                  |<   Œæ y)	a  
        Explode the current scene in-place around a point and vector.

        Parameters
        -----------
        vector : (3,) float or float
           Explode radially around a direction vector or spherically
        origin : (3,) float
          Point to explode around
        Ng      9@r¥   r   r“   rA  )r“   zexplode vector wrong shape!)rµ   r²   rC   Ú
asanyarrayr   r(   rŒ   r%   rD   r¹   r—   Ú
ValueErrorrÙ   )
r8   ÚvectorÚoriginrJ   rE   r¡   rµ   ÚoffsetÚ	projectedÚT_news
             r9   ÚexplodezScene.explodey  s3  € ð ˆ>Ø—]‘]ˆFØˆ>Ø—Z‘Z $Ñ&ˆFä—‘˜v¬R¯Z©ZÔ8ˆÜ—‘˜v¬R¯Z©ZÔ8ˆàŸ™×2Ô2ˆIØ'+§z¡z°)Ñ'<Ñ$ˆI�}Ø—}‘} ]Ñ3×<Ñ<ˆHä—v‘v˜i¬¯©°8¸QÓ)?Ó@ÀÀ!ÐDˆHà�|‰|˜rÒ!à" VÑ+¨vÑ5‘Ü—‘˜&Ó! TÒ)ÜŸF™F 6¨H°vÑ,=Ó?�	Ø )Ñ+‘ä Ð!>Ó?Ð?ð —N‘NÓ$ˆEØ�"�1�"�a�%‹L˜FÑ"‹LØ$)ˆD�J‰J�yÒ!ñ% 3r;   r²   c                 ó¤  — | j                  «       }t        j                  |d«      r|S t        |t        t
        t        j                  f«      xr t        |«      dk(  }|r?t        j                  t        j                  |«      |d   k(  «      rt        |d   «      }d}n|st        |«      }|�r&|j                  j                  D �]   }|j                  j                  |   }t        |«      dkD  sŒ,|j                  |   }|D ]°  }|j                  j                  j                  |   }|j!                  |j                  «       ||||j                  j                  j"                  ||f   j%                  dd«      |j                  j                  j"                  ||f   j%                  dd«      ¬	«       Œ² |j'                  |«       �Œ |j                  D ]V  }|j                  |   j(                  j*                  d   d
k(  sŒ-|j                  |   j-                  «       |j                  |<   ŒX |j                  j.                  D ]’  }	|j                  j%                  |	«      \  }
}|
j                  «       }
d|
dd…df<   |j                  |   j1                  |
«      j3                  |«      j1                  t        j4                  j7                  |
«      «       Œ” |j                  j                  j"                  }|D ]`  }d||   v sŒ||   }||   d   j                  «       }
|
dd…dfxx   |z  cc<   |
|d<    |j                  j8                  d|d   |d   dœ|¤Ž Œb i |j                  j                  _        t=        t?        j@                  «       «      |j                  j                  _!        |j                  j:                  jE                  «        �nôt        jF                  d«      |z  }t        jF                  d«      |z  }t        jH                  | j                  j.                  «      }t        jJ                  t        |«      ddf«      }dgt        |«      z  }tM        |«      D ]  \  }}| j                  |   \  ||<   ||<   Œ |j                  jE                  «        tO        jP                  |«      D �]  }||d      }||d      }t        jR                  ||«      }|j                  |   j(                  j*                  d   d
k(  r|j                  |   j1                  |«       n|j                  |   j1                  |«       tU        ||   ||   «      D ]i  \  }}
tW        jX                  ||
t        j4                  j7                  |«      g«      }|dd…dfxx   |z  cc<   |j                  j9                  |||¬«       Œk �Œ d|_-        |S )ao  
        Return a copy of the current scene, with meshes and scene
        transforms scaled to the requested factor.

        Parameters
        -----------
        scale : float or (3,) float
          Factor to scale meshes and transforms

        Returns
        -----------
        scaled : trimesh.Scene
          A copy of the current scene but scaled
        r¯   r“   r   Fr   r@   Nr'   )r%   rK   rJ   rL   rE   r'   r   rÍ   )r>   r?   rS   )r?   r@   r%   rA  ).rÙ   rC   r  r5   r¨   ÚtupleÚndarrayr\   r%  Úasarrayr°   r(   Úgeometry_nodesr%   rA   Úparentsr4   Ú	edge_datarš   rk   r’   r—   r  rŒ   rI   Úapply_scaleÚlinalgÚinvr7   r3   r[   ÚuuidÚuuid4Ú	_modifiedrX   r_   rœ   r™   Ú	enumerater	   ÚgrouprD   r  r   Ú	multi_dotrû   )r8   r²   r)  Úscale_is_3DrK   Únodes_with_geomÚgeomrº   ÚpÚkeyr›   re  ÚuvÚpropsÚscale_2DÚscale_3Dr6  rA   Ú
geometriesrŽ   rì   rm  r%   ÚoriginalÚnew_geomrE   s                             r9   rT  zScene.scaled   sú  € ð —‘“ˆô �;‰;�u˜cÔ"ØˆMô ! ¬¬u´b·j±jÐ(AÓBÒVÄsÈ5ÃzÐUVÁˆáœ2Ÿ6™6¤"§*¡*¨UÓ"3°u¸Q±xÑ"?Ô@ä˜% ™(“OˆEØ‰KÙÜ˜%“LˆEò ð $Ÿ\™\×8Õ8�	Ø"(§,¡,×"=Ñ"=¸iÑ"H�Ü�Ó'¨!Ó+Ø!Ÿ?™?¨9Ñ5�DÛ,˜Ø"ŸL™L×3Ñ3×;Ñ;¸AÑ>˜Ø×+Ñ+Ø%)§Y¡Y£[Ø&/Ø&'Ø-.Ø&,§l¡l×&=Ñ&=×&GÑ&GÈÈAÈÑ&O×&SÑ&SØ (¨$ó'ð &,§\¡\×%<Ñ%<×%FÑ%FÈÈ1ÀvÑ%N×%RÑ%RØ *¨Dó&ð ,õ ð -ð ×*Ñ*¨9Ö5ð% 9ð* $Ÿ_œ_�	Ø—?‘? 9Ñ-×6Ñ6×<Ñ<¸QÑ?À1ÓDØ17·±ÀÑ1K×1QÑ1QÓ1S�F—O‘O IÒ.ð -ð —|‘|×2Ô2�Ø%Ÿ|™|×/Ñ/°Ó4‘��9à—F‘F“H�Ø��"�1�"�a�%‘ð —‘ 	Ñ*×:Ñ:¸1Ó=×IÑIØóç!‘/¤"§)¡)§-¡-°Ó"2Õ3ð 3ð Ÿ™×/Ñ/×9Ñ9ˆIÛ�Ø˜y¨™}Ò,Ø% b™M�EØ! "™ hÑ/×4Ñ4Ó6�AØ�b�q�b˜!�e“H Ñ%“HØ&'�E˜(‘OØ'�F—L‘L×'Ñ'ÐR°2°a±5À2ÀaÁ5ÑRÈEÓRð  ð .0ˆF�L‰L×#Ñ#Ô*Ü03´D·J±J³LÓ0AˆF�L‰L×#Ñ#Ô-Ø�L‰L×Ñ×%Ñ%Ö'ô —v‘v˜a“y 5Ñ(ˆHä—v‘v˜a“y 5Ñ(ˆHô —H‘H˜TŸZ™Z×6Ñ6Ó7ˆEÜŸ™¤3 u£:¨q°!Ð"4Ó5ˆJØ˜¤# e£*Ñ,ˆJô % UÖ+‘��4Ø/3¯z©z¸$Ñ/?Ñ,�
˜1‘˜z¨!š}ð ,ð �L‰L×ÑÔ ä!Ÿ™¨
×3�à% e¨A¡hÑ/�à% e¨A¡hÑ/�äŸ6™6 (¨HÓ5�à—?‘? 8Ñ,×5Ñ5×;Ñ;¸AÑ>À!ÒCà—O‘O HÑ-×=Ñ=¸hÕGð —O‘O HÑ-×=Ñ=¸hÔGä" 5¨¡<°¸EÑ1BÖC‘G�D˜!ä $§¡°¸!¼R¿Y¹Y¿]¹]È8Ó=TÐ/UÓ V�Ià˜b˜q˜b !˜eÓ$¨Ñ-Ó$à—L‘L×'Ñ'Ø!%¨iÀ(ð (õ ò  Dð 4ð4 ˆŒàˆr;   c                 óp  — | j                   j                  «       D ��ci c]  \  }}||j                  «       “Œ }}}t        | d«      r| j                  €d}n| j
                  j                  «       }t        || j                  j                  «       | j                  j                  «       |¬«      }|S c c}}w )z 
        Return a deep copy of the current scene

        Returns
        ----------
        copied : trimesh.Scene
          Copy of the current scene
        rû   N)r%   r(   r'   r)   )	r%   rW   rÙ   rz   rû   r)   r$   r(   r'   )r8   rº   r½   r%   r)   Úcopieds         r9   rÙ   z
Scene.copy(  sœ   € ð -1¯M©M×,?Ñ,?Ô,AÔBÑ,A¡D A q�A�q—v‘v“x‘KÐ,AˆÑBä�t˜YÔ'¨4¯<©<Ð+?à‰Fð —[‘[×%Ñ%Ó'ˆFäØØ—*‘*—/‘/Ó#Ø—]‘]×'Ñ'Ó)Øô	
ˆð ˆùó Cs   žB2Úviewerc                 óÞ   — |€ddl m}  |«       }|sd}|dk(  rddl m}  || fi |¤ŽS |dk(  rddl m}  || fi |¤ŽS |dk(  rddl m}  || fi |¤ŽS t        |«      r	 || fi |¤ŽS t        d	«      ‚)
a¨  
        Display the current scene.

        Parameters
        -----------
        viewer
          What kind of viewer to use, such as
          `gl` to open a pyglet window
          `jupyter` for a jupyter notebook
          `marimo'` for a marimo notebook
          None for a "best guess"
        kwargs
          Passed to viewer, such as `smooth=False` which will turn
          off automatic smooth shading
        r   )Úin_notebookÚgl)ÚSceneViewerÚjupyter)Úscene_to_notebookÚmarimo)Úscene_to_mo_notebookzJInvalid value for viewer: not 'gl', 'jupyter', 'marimo', callable, or None)r}  r  r�  rƒ  r…  ÚcallablerX  )r8   r}  rC  r  r�  rƒ  r…  s          r9   Úshowz
Scene.showD  s™   € ð* ˆ>å,ñ !“]ˆFÙØ�à�TŠ>õ -á˜tÑ. vÑ.Ð.Ø�yÒ Ý2á$ TÑ4¨VÑ4Ð4Ø�xÒÝ5á'¨Ñ7°Ñ7Ð7Ü�fÔñ ˜$Ñ) &Ñ)Ð)äØ\óð r;   c                 óN   — t        | |g| j                  j                  g¬«      }|S )a`  
        Concatenate the current scene with another scene or mesh.

        Parameters
        ------------
        other : trimesh.Scene, trimesh.Trimesh, trimesh.Path
           Other object to append into the result scene

        Returns
        ------------
        appended : trimesh.Scene
           Scene with geometry from both scenes
        )Úcommon)Úappend_scenesr(   r&   )r8   Úotherr)  s      r9   Ú__add__zScene.__add__y  s&   € ô   e˜}°d·j±j×6KÑ6KÐ5LÔMˆØˆr;   )NÚworldNNNNN)NNNNN)rf   N)NNN)gñhãˆµøä>)F)rf   ztrimesh.Trimesh)NNr~   )rf   r$   )OÚ__name__Ú
__module__Ú__qualname__Ú__doc__r"   r   r6   r!   r   rý   r   r    ÚLightr   r:   rI   r[   r4   rh   rk   rt   r   r   ry   ré   r2   ÚpropertyÚboolrŠ   r�   r   Úcache_decoratorr   r£   r–   r­   r°   r²   rµ   r·   rÆ   rÈ   rÊ   rÔ   rÖ   r×   rà   rß   r¨   rð   ró   r  r+   Úsetterr   r`  r   r  r)   r  r*   r  r   ræ   r.  r0  r:  r=  r   ÚbytesrI  r   rU  r^  rT  rÙ   r   r‡  rŒ  rA  r;   r9   r$   r$   $   sþ  „ ñð *.Ø&Ø $Ø#'Ø(,Ø26Ø+/ñ99à $Ñ&ð99ð ð99ð ˜‘+ð	99ð
 ˜DÑ ð99ð —‘ Ñ%ð99ð ˜Ÿ™Ñ(¨4Ñ/ð99ð " D™.ó99òvð& &*Ø $Ø,0Ø$(Ø $ñpàðpð ˜d‘?ðpð ˜‘:ð	pð
 # T™/ðpð ˜T‘>ðpð ˜‘+ópðd: S¨3¡Y°Ñ%9ð :¸dó :ó(	>ð $(Ø%)Ø%)ñ	&à˜D‘ð&ð ˜d‘Nð&ð ˜d‘Nð	&ð
 
ó&ð<D˜#ó Dð$ ð
'˜$ò 
'ó ð
'ð ð7˜$ò 7ó ð7ð* ×Ñð*  S¨'°'Ñ*:Ð%:Ñ ;ò *ó ð*ðX ×ÑðV˜ Ñ(¨4Ñ/ò Vó ðVð" ×Ñð3˜ Ñ)¨DÑ0ò 3ó ð3ð ×Ñð0�uò 0ó ð0ð ×Ñð˜' 'Ñ*¨TÑ1ò ó ðð ×Ñð!D˜Wò !Dó ð!DðF ×Ññ
ó ð
òFð  ×Ñð
�eò 
ó ð
ð" ×Ñð
˜ò 
ó ð
ð" ×Ñð8˜7 7Ñ+ò 8ó ð8ð@ ×Ññ
-ó ð
-ð ×Ñð	T d¨3°¨8¡nò 	Tó ð	Tð ×Ñð1 ò 1ó ð1ð ×Ñð()  d¨3¡i¡ò ()ó ð()ñTJ°Hð JÈó Jð< MQñ1à	�‰ó1ðf ñ	/ó ð	/ð ×Ñð	. yò 	.ó ð	.ð(˜U 7¨7Ñ#3°W¸WÑ5EÀwÈuÁ~Ð#UÑVó (ð6 ð˜Ÿ™ò ó ðð$ ‡]�]ð˜WŸ^™^¨dÑ2ò ó ðð ðE˜Dò Eó ðEð ð˜˜XŸ^™^Ñ,ò ó ðð( ‡]�]ð	˜X h§n¡nÑ5ò 	ó ð	ó)ñ.8 ð 8°°h±ó 8ótTð -˜Xó -ð˜Xð ¨'ó ð< ×Ññ
*ó ð
*ó
ñ*
°uó 
ð, ð�s˜T‘zò ó ðð& ‡\�\ð˜3ò ó ðñ' Sð '°ð 'À'ó 'ôR%*ðNF˜H yÑ0ð F°Wó FóPð< "ñ3àó3ójr;   r$   c           
      ó˜  — t        | t        «      r| S i }t        j                  | «      rQ| D �cg c]  }|j	                  t        |di «      «      ‘Œ  c} t        | |¬«      }t        d„ | D «       d«      |_        |S t         | j                  di |¤Žt        | j                  «      ¬«      }t        | j                  «      |_        |S c c}w )zÑ
    Given a geometry, list of geometries, or a Scene
    return them as a single Scene object.

    Parameters
    ----------
    geometry : splittable

    Returns
    ---------
    scene: trimesh.Scene
    r'   )r'   c              3   óN   K  — | ]  }|j                   €Œ|j                   –— Œ y ­wr~   )rY   rã   s     r9   r�   zsplit_scene.<locals>.<genexpr>¤  s   è ø€ ÐQ±¨1¸A¿H¹HÑ<P˜aŸh�h±ùs   ‚%”%NrA  )r5   r$   r   rV   r7   ÚgetattrÚnextÚ_sourceÚsplitr   r'   rY   )r%   rC  r'   r½   rÃ   s        r9   Úsplit_scenerž  ‹  s¾   € ô �(œEÔ"Øˆð €Hô ×Ñ˜Ô!Ù>FÓG¹h¸ˆ�‰œ  J°Ó3Õ	4¸hÒGä�h¨Ô2ˆÜÑQ±ÓQÐSWÓXˆŒð €Lô ØˆH�N‰NÑ$˜VÑ$Ü˜h×/Ñ/Ó0ô
ˆô ! §¡Ó1ˆŒà€Lùò 	Hs   ®#Cc                 ó4  ‡‡‡‡— t        | t        «      r| S ‰€|gŠi }g }t        ‰«      Št        «       Šˆˆˆˆfd„}| D �]  }t        |d«      r|j	                  «       }t        |t        «      s!t        t        |«      j                  › d�«      ‚i }|j                  j                  «       D ]*  \  }}	t        ||j                  «       ¬«      }
|
||<   |	||
<   Œ, i Št        «       Š|j                  j                  «       D ]@  \  }}} ||«       ||«      }}d|v r|d   |v r||d      |d<   |j                  |||f«       ŒB ‰j                  ‰«       �Œ t        |¬«      }|j                  j!                  |«       |j                  j                  |«       |S )a‡  
    Concatenate multiple scene objects into one scene.

    Parameters
    -------------
    iterable : (n,) Trimesh or Scene
       Geometries that should be appended
    common : (n,) str
       Nodes that shouldn't be remapped
    base_frame : str
       Base frame of the resulting scene

    Returns
    ------------
    result : trimesh.Scene
       Scene containing all geometry
    c                 óˆ   •— | ‰v r‰|    S | ‰vr"| ‰v r| t        j                  «       z   }|‰| <   |} ‰j                  | «       | S )a  
        Remap node to new name if necessary

        Parameters
        -------------
        node : hashable
           Node name in original scene

        Returns
        -------------
        name : hashable
           Node name in concatenated scene
        )r   Ú	unique_idÚadd)rì   rN   r‰  Úconsumedr*  Úmap_nodes     €€€€r9   Ú
node_remapz!append_scenes.<locals>.node_remapÒ  sZ   ø€ ð  �8ÑØ˜D‘>Ð!ð �vÑ $¨(Ñ"2àœ$Ÿ.™.Ó*Ñ*ˆDØ!ˆH�T‰NØˆDð 	�‰�DÔØˆr;   rÃ   z is not a scene!rP   r%   r-   )r5   r$   rh   rz   rÃ   rX  ÚtyperŽ  r%   rW   r   r]   r(   r4  r¹   r7   r5  )Úiterabler‰  r&   r%   r8  r¥  ÚsÚmap_geomra   rb   rN   ÚaÚbÚattrr)  r£  r*  r¤  s    `             @@@r9   rŠ  rŠ  °  s�  û€ ô$ �(œEÔ"Øˆà€~Ø�ˆð €Hà€Eô �‹[€Fä‹u€H÷ôB ˆä�1�gÔØ—‘“	ˆAä˜!œUÔ#Ü¤ Q£× 0Ñ 0Ð1Ð1AÐBÓCÐCð ˆØ—J‘J×$Ñ$Ö&‰DˆAˆqä Q°·±³ÔAˆDàˆH�Q‰KàˆH�TŠNð 'ð ˆä“%ˆØŸ'™'×-Ñ-Ö/‰JˆAˆq�$á˜a“=¡*¨Q£-ˆqˆAð ˜TÑ! d¨:Ñ&6¸(Ñ&BØ#+¨D°Ñ,<Ñ#=��ZÑ à�L‰L˜!˜Q ˜Õ&ð 0ð 	�‰˜Ö ðI ôN ˜jÔ)€FØ
‡L�L×Ñ˜uÔ%Ø
‡O�O×Ñ˜8Ô$à€Mr;   rÃ   rñ   rf   c           	      óZ  — | j                   j                  «       }| j                  D �]  }t        |«      dk  rŒ|d   }| j                   |   \  }}| j                  |   j
                  j                  t        j                  «      }|dd D ]¦  }| j                   |   \  }	}
| j                  |
   j
                  j                  t        j                  «      }|j                  |j                  k7  rŒet        ||ddd¬«      \  }}}||k  sŒ|j                  |t        j                  |	|«      |¬«       Œ¨ �Œ t        |j                  j                  «       «      }t!        | j                  j#                  «       D ��ci c]  \  }}||v sŒ||j                  «       “Œ c}}|¬	«      S c c}}w )
ad  
    If a scene has been "baked" with meshes it means that
    the duplicate nodes have *corresponding vertices* but are
    rigidly transformed to different places.

    This means the problem of finding ab instance transform can
    use the `procrustes` analysis which is *very* fast relative
    to more complicated registration problems that require ICP
    and nearest-point-on-surface calculations.

    TODO : construct a parent non-geometry node for containing every group.

    Parameters
    ----------
    scene
      The scene to handle.
    cost_threshold
      The maximum value for `procrustes` cost which is "squared mean
      vertex distance between pair". If the fit is above this value
      the instance will be left even if it is a duplicate.

    Returns
    ---------
    dedupe
      A copy of the scene de-duplicated as much as possible.
    r   r   r   NTF)Útranslationr²   Ú
reflection)r@   r%   r2  )r(   rÙ   rð   r\   r%   r’   ÚviewrC   ra  r—   r   r7   rD   rh   rc  r]   r$   rW   )rÃ   rñ   r(   rm  Ú	node_baser¿   Ú	geom_baserF   rì   Únode_matÚ	node_geomÚnode_verticesr@   Ú_pÚcostr�   ra   rb   s                     r9   ró   ró   !  s~  € ð8 �K‰K×ÑÓ€Eà×&Õ&ˆäˆu‹:˜Š>Øð ˜!‘Hˆ	à—{‘{ 9Ñ-‰ˆˆ9à�~‰~˜iÑ(×1Ñ1×6Ñ6´r·z±zÓBˆà˜!˜"“IˆDà"'§+¡+¨dÑ"3ÑˆH�ið "ŸN™N¨9Ñ5×>Ñ>×CÑCÄBÇJÁJÓOˆMð ×"Ñ" d§j¡jÒ0Øô  *Ø�m°¸UÈuô ÑˆF�B˜ð �nÓ$à—‘˜T¬"¯&©&°¸6Ó*BÈY�ÕWò# ð 'ô@ �U×)Ñ)×.Ñ.Ó0Ó1€Jô Ø*/¯.©.×*>Ñ*>Ô*@ÔTÑ*@¡$ ! QÀAÈÂO�!�Q—V‘V“X‘+Ð*@ÒTØôð ùÛTs   Å=F'
Æ
F'
)Nr�  )g�íµ ÷Æ°>)4r/   ri  r&  rÙ   r   Úhashlibr   Útypingr   ÚnumpyrC   r‚   r   r   r	   r
   r   r   r   Ú	constantsr   Úexchanger   Úparentr   r   Úregistrationr   Útypedr   r   r   r   r   r   r   r   r   r   r   r   r    rA   r!   r6   r[   r"   Ú__annotations__r$   rž  rŠ  ró   rA  r;   r9   Ú<module>rÁ     s¯   ðÜ Û Û Ý Ý Ý ó ç O× OÑ OÝ Ý ß )Ý %÷÷ ÷ õ ß Ý "ð $ h¨xÑ&8Ñ8¸4ÀÀXÀÑ;NÑNÐQZÑZ€ˆyÓ ZôdˆJô dòN+"óJnñbD ð D¸ð DÈEô Dr;   