
    Ti                     r   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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$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e         ee.ef         ef         Z/ G d de          Z0d Z1ddZ2dde0dede0fdZ3dS )    N)deepcopy)sha256   )cachingconvexgroupinginertiatransformationsunitsutil)log)export)Geometry
Geometry3D)
procrustes)	ArrayLikeDictFloatingIntegerIterableListNDArrayOptionalSequenceTupleUnion
ViewerTypefloat64int64)unique_name   )cameraslighting)
SceneGraphc                   6   e Zd ZdZ	 	 	 	 	 	 	 dRdee         dedee         dee         dee	j
                 d	eeej                          d
ee         fdZd Z	 	 	 	 	 dSdedee         dee         dee         dee         dee         fdZdeeeef         ddfdZdTdZ	 	 	 dUdee         dee         dee         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e!                  fd            Z#ej         deee!                  fd            Z$ej         de%fd             Z&ej         deee!                  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*            Z0ej         de1e1e                  fd+            Z2dVd-edd fd.Z3	 dSde	j
        fd/Z4ed0             Z5e5j6        d1e7fd2            Z5de8ee!         ee!         ee9         f         fd3Z:ede	j
        fd4            Z;e;j6        dee	j
                 fd5            Z;edefd6            Z<ede1ej                 fd7            Z=e=j6        d	eej                 fd8            Z=dTd9Z>dWd;ede1e?         fd<Z@dXd>ZAde?fd?ZBd@edd fdAZCej         dB             ZDdYdCZEdZdeFfdDZGedee         fdE            ZHeHj6        dFefdG            ZHdWdHedIedd fdJZIdYdTdKZJdLeee7f         dd fdMZKd[dNZL	 dZdOeMfdPZNdQ ZOdS )\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worldgeometry
base_framemetadatagraphcameralightscamera_transformc                    t          j                    | _        t          |          | _        t          j        | j                  | _        || 	                    |           i | _
        t          |t                    r| j
                            |           ||| _        ||| _        ||| _        ||| _        dS dS dS )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           M/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/scene/scene.py__init__zScene.__init__/   s    > $/11  :666
 m>>>h''' h%% 	+M  ***DJ DK DK+(8%%% ++    c                     | j         j        }| j         j        j        |         D ]E}t	          j        || j         |         d                   }| j                             |||           F| 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dotr:   )r;   	transformbasechildcombineds        r<   apply_transformzScene.apply_transformj   sn     z$Z*3D9 	P 	PEviE):1)=>>HJhOOOOr>   	node_name	geom_nameparent_node_namerH   c                     |dS t          j        |          r fd|D             S t          |t                    r! fd|                                D             S t          |t
                    rU |z   } j                                          j                            |j                   |j	        j
         j	        _
        dS }nTd|j        v r|j        d         }n=|j        j        |j        j        }n$dt          t           j                            z   }t!          | j                                                  }| j        |<   9 j	        j
        j                                        }	t!          ||	          |	vsJ t'          j        d           j	                            |dd	i
           S )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).
        Nc           
      F    g | ]}                     |           S ))r(   rM   rN   rO   rH   r*   r7   ).0valuerN   r*   rM   rO   r;   rH   s     r<   
<listcomp>z&Scene.add_geometry.<locals>.<listcomp>   sR     
 
 
  !!"''%5'% "  
 
 
r>   c                 H    i | ]\  }}|                     ||           S ))r(   rN   r*   rR   )rS   kvr*   r;   s      r<   
<dictcomp>z&Scene.add_geometry.<locals>.<dictcomp>   sD       Aq 4$$a1x$PP  r>   name	geometry_startcontains   visibleT)rB   rA   rC   r(   geometry_flagsr*   )r   is_sequencer8   r9   itemsr&   r(   clearr:   r+   rD   r*   source	file_namestrlenr    keys	node_datarF   eye)
r;   r(   rM   rN   rO   rH   r*   concatrZ   existings
   ` `````   r<   r7   zScene.add_geometryz   s?   L Fh'' 	
 
 
 
 
 
 
 
 
 &
 
 
 
 $'' 	    $NN,,   
 %(( 	H_FM!!!M  111$*L$;DJ!F  DDx((($V,DD_&2?,DD S%7%7!8!88D 0B0B0D0DEEE&d  z,6;;==H $D(33IH,,,,q		I
'%t, 	 	
 	
 	
 r>   namesreturnc                      t          |t                    r|g}t          |          } j                            |            fd|D              dS )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
        c                 F    g | ]}j                             |d           S N)r(   pop)rS   rZ   r;   s     r<   rU   z)Scene.delete_geometry.<locals>.<listcomp>   s+    9994		4	&	&999r>   N)r8   rg   setr+   remove_geometries)r;   rn   s   ` r<   delete_geometryzScene.delete_geometry   sa     eS!! 	GEE

 	
$$U+++99995999999r>   c                     ddl m} | j                                        D ](}t	          j        |d          r ||          |_        )dS )zl
        Strip visuals from every Trimesh geometry
        and set them to an empty `ColorVisuals`.
        r   )ColorVisualsTrimesh)meshN)visual.colorrx   r(   valuesr   is_instance_namedvisual)r;   rx   r(   s      r<   strip_visualszScene.strip_visuals   sg    
 	0/////,,.. 	> 	>H%h	:: >".,H"="="=	> 	>r>   percent
face_count
aggressionc                     i }| j                                         D ]0\  }}t          |d          r|                    |||          ||<   1| j                             |           dS )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)r   r   r   N)r(   rc   hasattrr   r:   )r;   r   r   r   updatesrW   rX   s          r<   r   z!Scene.simplify_quadric_decimation  s    , M'')) 	 	DAqq788 ::#
z ;  
 	W%%%%%r>   c                 D   | j         t          | j        j                                                  g}|                    fd                                D                        t          j        d	                    |          
                    d                    S )z
        Return information about scene which is hashable.

        Returns
        ---------
        hashed
          String hashing scene.
        c              3   f   K   | ]+}t          |                                                   V  ,d S rr   )hexr5   )rS   rW   r(   s     r<   	<genexpr>z!Scene.__hash__.<locals>.<genexpr>8  s;      MMHQK002233MMMMMMr>    zutf-8)r(   r   r+   rD   r5   extendri   r   	hash_fastjoinencode)r;   hashabler(   s     @r<   r5   zScene.__hash__)  s     = 
-668899:MMMMX]]__MMMMMM !2!2!9!9'!B!BC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   )rh   r(   r;   s    r<   is_emptyzScene.is_empty;  s     4=!!Q&&r>   c                      t           j                  dk    rdS 	  fd j        j        D             }n# t          $ r Y dS w xY w|t           j                                                  k    S )z
        Is every geometry connected to the root node.

        Returns
        -----------
        is_valid : bool
          Does every geometry have a transform
        r   Tc                 6    h | ]}j         |         d          S r!   )r+   )rS   ir;   s     r<   	<setcomp>z!Scene.is_valid.<locals>.<setcomp>V  s$    NNNq$*Q-*NNNr>   F)rh   r(   r+   nodes_geometryBaseExceptionrt   ri   )r;   
referenceds   ` r<   is_validzScene.is_validH  s     t}""4	NNNNDJ4MNNNJJ 	 	 	55	
 S!3!3!5!56666s   6 
AAc                 "   i }d | j                                         D             }|                    d |                                D                        | j        j        D ]}| j        |         \  }}|                    |          }|*t          j        |ddddf         |j                  }t          j	        |
                    d          |dddf         z   |                    d          |dddf         z   g          ||<   |S )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}
        c                     i | ]<\  }}|t          |d           rt          |j                  dk    r|j        n|j        =S )verticesr   )r   rh   r   boundsrS   rW   ms      r<   rY   z(Scene.bounds_corners.<locals>.<dictcomp>m  sY     
 
 
1 WQ
33YAJ!8K8KqzzQRQY
 
 
r>   c                     i | ]N\  }}||j         d         dk    |t          j        |t          j        t	          |                    f          OS )Nr!   r   )shaperF   column_stackzerosrh   )rS   rW   rX   s      r<   rY   z(Scene.bounds_corners.<locals>.<dictcomp>s  sX       Aq=QWQZ1__ 2?ArxA'7'7#899%4__r>   N   r!   axis)r(   rc   r:   r+   r   getrF   rG   Tarrayminmax)r;   cornersr   rM   rH   geometry_namepointsrG   s           r<   bounds_cornerszScene.bounds_corners^  s@    
 
++--
 
 

 	 $NN,,  	
 	
 	
 2 	 	I'+z)'<$I}\\-00F~&2A2rr6*FH55C!#a9RaRU#33SWW!W__yQSRSQSUVQVGW5WX" "GI r>   c                 >   | j         }t          |          dk    rdS t          j        t	          | j                                                             }t          j        |                    d          |                    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   rh   rF   vstacklistr|   r   r   r   r   )r;   r   r   s      r<   r   zScene.bounds  s     ,~!##4)D!4!;!;!=!=>>??x!,,gkkqk.A.AB"*UUUUr>   c                 j    | j         }|dS t          j        |d                              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   rF   diffreshape)r;   r   s     r<   extentszScene.extents  s8     >4wvA&&&..r222r>   c                 f    | j         }|dS t          |dz                                  dz            S )z
        The approximate scale of the mesh

        Returns
        -----------
        scale : float
          The mean of the bounding box edge lengths
        N      ?r   g      ?)r   floatsum)r;   r   s     r<   scalezScene.scale  s8     ,?3gqj%%''3.///r>   c                 R    | j         }|dS 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   rF   mean)r;   r   centroids      r<   r   zScene.centroid  s0     >474;Q///r>   c                    d | j                                         D             d | j                                         D             | j        fdj        D             }t	          j        fd|D             t          j                  }t	          j        fd|D             t          j                  }||                                z  }||                    d          z                      d	          S )
z
        Find the center of mass for every instance in the scene.

        Returns
        ------------
        center_mass : (3,) float
          The center of mass of the scene
        c                 D    i | ]\  }}t          |d           ||j        S )center_mass)r   r   r   s      r<   rY   z%Scene.center_mass.<locals>.<dictcomp>  s@     
 
 
1q-((
q}
 
 
r>   c                 D    i | ]\  }}t          |d           ||j        S )mass)r   r   r   s      r<   rY   z%Scene.center_mass.<locals>.<dictcomp>  s/    RRRdawq&?Q?QR16RRRr>   c                      g | ]
}|         S  r   )rS   nr+   s     r<   rU   z%Scene.center_mass.<locals>.<listcomp>  s    ;;;E!H;;;r>   c           	          g | ]?\  }}|v 	t          j        |t          j        |         d                     dd         @S )r!   Nr   )rF   rG   append)rS   matgr   s      r<   rU   z%Scene.center_mass.<locals>.<listcomp>  sW       C## sBIk!na8899"1"=###r>   r   c                 &    g | ]\  }}|         S r   r   )rS   _r   r   s      r<   rU   z%Scene.center_mass.<locals>.<listcomp>  s!    9991DG999r>   )r   r!   r   r   )	r(   rc   r+   r   rF   r   r   r   r   )r;   instancetransformedweightsr   r+   r   s       @@@r<   r   zScene.center_mass  s&   
 
++--
 
 

 SRdm&9&9&;&;RRR 
;;;;e&:;;; h   &  
 *
 
 
 (9999999LLL7;;== goog666;;;CCCr>   c                 \    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`
        scenerH   )r	   scene_inertiar
   translation_matrixr   r   s    r<   moment_inertiazScene.moment_inertia  s1     $/"DTEU"V"V
 
 
 	
r>   c                 .    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   )r;   rH   s     r<   moment_inertia_framezScene.moment_inertia_frame  s     $49EEEEr>   c                      d  j                                         D             t           fd j        j        D             d          S )z
        What is the summed area of every geometry which
        has area.

        Returns
        ------------
        area : float
          Summed area of every instanced geometry
        c                 D    i | ]\  }}t          |d           ||j        S area)r   r   rS   r   r   s      r<   rY   zScene.area.<locals>.<dictcomp>  s/    SSStq!6@R@RSAFSSSr>   c              3   f   K   | ]+}                     j        |         d          d          V  ,dS r!           Nr   r+   )rS   r   areasr;   s     r<   r   zScene.area.<locals>.<genexpr>  s<      QQ!UYYtz!}Q'--QQQQQQr>   r   r(   rc   r   r+   r   )r;   r   s   `@r<   r   z
Scene.area  s\     TSt}':':'<'<SSSQQQQQtz7PQQQSV
 
 	
r>   c                      d  j                                         D             t           fd j        j        D             d          S )z
        What is the summed volume of every geometry which
        has volume

        Returns
        ------------
        volume : float
          Summed area of every instanced geometry
        c                 D    i | ]\  }}t          |d           ||j        S r   )r   volumer   s      r<   rY   z Scene.volume.<locals>.<dictcomp>-  s/    VVV$!Q71fCUCUV!QXVVVr>   c              3   f   K   | ]+}                     j        |         d          d          V  ,dS r   r   )rS   r   r;   r   s     r<   r   zScene.volume.<locals>.<genexpr>0  s<      RR1VZZ
1a(#..RRRRRRr>   r   r   )r;   r   s   `@r<   r   zScene.volume!  s\     WV$-*=*=*?*?VVVRRRRR
8QRRRTW
 
 	
r>   c           	      $   g }g }| j         j        D ]}| j         |         \  }}| j        |         }t          |d          s0|                    t          j        |j                                        	                    d          |                     |                    t          j        |t          |j                                       t          j        |          | j        d<   t          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   )rC   triangles_node)r   r   r   )r+   r   r(   r   r   r
   transform_pointsr   copyr   rF   tilerh   hstackr6   r   )r;   r   r   rM   rH   r   r(   s          r<   r   zScene.triangles3  s    	2 	O 	OI'+z)'<$I} }]3H8[11 0&++--55g>>y     !!"')S9K5L5L"M"MNNNN(*	.(A(A$%y##++J777r>   c                 *    | 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   r6   )r;   populates     r<   r   zScene.triangles_nodeT  s     >{+,,r>   c                 H    d | j                                         D             S )z
        Look up geometries by identifier hash.

        Returns
        ---------
        identifiers
          {Identifier hash: key in self.geometry}
        c                 $    i | ]\  }}|j         |S r   identifier_hash)rS   rZ   rz   s      r<   rY   z.Scene.geometry_identifiers.<locals>.<dictcomp>k  s!    SSSztT$dSSSr>   )r(   rc   r   s    r<   geometry_identifierszScene.geometry_identifiersa  s'     TST]=P=P=R=RSSSSr>   c                    d                     d | j                                        D                       t          t	          | j                            z   }t          |                                                                          S )z8
        Get a unique identifier for the scene.
        r   c              3   $   K   | ]}|j         V  d S rr   r   rS   r   s     r<   r   z(Scene.identifier_hash.<locals>.<genexpr>r  s%      IIQq(IIIIIIr>   )	r   r(   r|   rg   hashr+   r   r   	hexdigest)r;   dumps     r<   r   zScene.identifier_hashm  sv    
 wwII$-2F2F2H2HIIIIICM
 M
 
 dkkmm$$..000r>   c                 l   t          | j                  dk    rg S d | j                                        D             | j        fdj        D             }t          j        t                    fd|                                D              t                                                    S )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   c                 `    i | ]+\  }}t          |d           |t          |j        d          ,S )r      )r   intr   r   s      r<   rY   z)Scene.duplicate_nodes.<locals>.<dictcomp>  sL     
 
 
1q+,,
s1$b))
 
 
r>   c                 T    i | ]$}|                     |         d                    %S r   )r   )rS   noder+   hashess     r<   rY   z)Scene.duplicate_nodes.<locals>.<dictcomp>  s/    WWW$T6::eDk!n55WWWr>   c                 P    g | ]"\  }}||                              |          #S rr   )r   )rS   r  hashed
duplicatess      r<   rU   z)Scene.duplicate_nodes.<locals>.<listcomp>  s@     	
 	
 	
f! v%%d++!!!r>   )	rh   r(   rc   r+   r   r2   defaultdictr   r|   )r;   	node_hashr
  r+   r  s     @@@r<   duplicate_nodeszScene.duplicate_nodesw  s     t}""I
 
++--
 
 
 
 XWWWW%BVWWW	 !,T22
	
 	
 	
 	
 ) 1 1	
 	
 	
 	
 J%%''(((r>   h㈵>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)r;   r  s     r<   r  zScene.reconstruct_instances  s    6 %T.IIIIr>   c                 D   |t          j        ddg          }t          | j                  dk    rGt	          j        |          | _        t          j        d          | j        | j        j	        <   | j        S |t          j
        d          }t          j        | }t	          j        | j        ||||          }t          | d	          r"| 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
        N<   -   r   )fovr_   r   )r  rotationdistancecenter_camera)r  
resolution)rF   r   rh   r(   r"   Camerar  rk   r+   rZ   r   r
   euler_matrixlook_atr   r   r  r  )r;   anglesr  r  r  r  r  rH   s           r<   
set_camerazScene.set_camera  s   , ;(B8$$C t}""">c222DL,.F1IIDJt|()<>Xa[[F"/8OKS8hv
 
 
	 4## 	J(@"DL%*4' #>cjIIIDL(1
4<$%|r>   c                 <    | 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,   rZ   r   s    r<   r.   zScene.camera_transform  s     z$+*+A..r>   rC   c                 .    || j         | j        j        <   dS )z
        Set the camera transform in the base frame

        Parameters
        ----------
        camera_transform : (4, 4) float
          Camera transform in the base frame
        Nr!  )r;   rC   s     r<   r.   zScene.camera_transform  s     (.
4;#$$$r>   c                     | 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   rF   	ones_liketranslation_from_matrix)r;   vectorspixelsrH   originss        r<   camera_rayszScene.camera_rays
  sp      +--//)	!27IQVWWW,w''/*Q+
 +
 
 ''r>   c                 X    | j         s|                                 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    r<   r,   zScene.camera%  s4      	%??$$$|'''|r>   c                     |dS || _         dS )z
        Set a camera object for the Scene.

        Parameters
        -----------
        camera : trimesh.scene.Camera
          Camera object for the scene
        N)r  )r;   r,   s     r<   r,   zScene.camera8  s     >Fr>   c                 4    t          | d          o| j        d uS )Nr  )r   r  r   s    r<   r-  zScene.has_cameraF  s    tY''DDL,DDr>   c                     t          | d          r| j        Ct          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)r   r1  r#   	autolightzipr+   rZ   )r;   r-   rD   Lr   s        r<   r-   zScene.lightsJ  so     tY'' 	"4<+?!)!3D!9!9FJFJ// ' '1%&
16""!DL|r>   c                     || _         dS )z
        Assign a list of light objects to the scene

        Parameters
        --------------
        lights : [trimesh.scene.lighting.Light]
          Lights in the scene.
        N)r1  )r;   r-   s     r<   r-   zScene.lights_  s     r>   c                 0   | j         st          j        | j        d          rdS t          j        d          }| j         |dddf<   t          | j        j                  dz   }| j                            || j        j        |           || j        _        dS )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   Nr_   r   _Ir@   )	r   rF   allcloser   rk   rg   r+   r)   r:   )r;   rC   new_bases      r<   rezerozScene.rezerok  s     = 	BKs;; 	F rr1u tz,--4
$**? 	 	
 	
 	
 !)
r>   Fconcatenatec                 L   g }| j         j        D ]}| j         |         \  }}| j        |                                         }t	          |d          rct          j        |t
          j        d          }d|ddddf<   |                                s|	                                }n|ddddf         }|
                    |           ||j        d<   ||j        d	<   |                    |           |r0t          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:0yE>)atolTNr   r   rZ   r  zd`Scene.dump(concatenate=True)` DEPRECATED FOR REMOVAL APRIL 2025: replace with `Scene.to_geometry()`)category
stacklevel)r+   r   r(   r   r   r   isclose	_IDENTITYallr=  rL   r*   r   warningswarnDeprecationWarningr;  )r;   r;  resultrM   rH   r   currentchecks           r<   r   z
Scene.dump  sG   * 2 	# 	#I'+z)'<$I}mM27799G w(( 	2YTJJJ $bqb"1"fyy{{ 2%mmooGG !*"1"bqb& 1I ##I...'4GV$'0GV$ MM'"""" 	,Mv+    #F+++r>   trimesh.Trimeshc                 t    ddl m t          j        fd|                                 D                       S )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   )ry   c                 4    g | ]}t          |          |S r   )r8   )rS   dry   s     r<   rU   z!Scene.to_mesh.<locals>.<listcomp>  s(     R R Rq:a;Q;Q R R R Rr>   )rI   ry   r   r;  r   )r;   ry   s    @r<   to_meshzScene.to_mesh  sG     	#"""""  R R R RDIIKK R R RSSSr>   c                 N    t          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    r<   to_geometryzScene.to_geometry  s     		,,,r>   r  c                 ,     j         }|j                            |          fd|                                D             }t	          |          }|                    |           d |D             } fd|D             }t          ||          }|S )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.
        c                 (    g | ]}|d          v |S )r   r   )rS   enodess     r<   rU   z"Scene.subscene.<locals>.<listcomp>  s"    AAAq1Q45=====r>   r0   c                 >    h | ]}d |d         v |d         d          S )r(   r   r   )rS   rS  s     r<   r   z!Scene.subscene.<locals>.<setcomp>  s/    PPPqZ1Q4=O=O!A$z*=O=O=Or>   c                 ,    i | ]}|j         |         S r   )r(   )rS   rW   r;   s     r<   rY   z"Scene.subscene.<locals>.<dictcomp>  s"    @@@AAt}Q'@@@r>   r(   r+   )r+   rD   
successorsto_edgelistr$   from_edgelistr&   )r;   r  r+   edgesgeometry_namesr(   rG  rT  s   `      @r<   subscenezScene.subscene  s      
 ++D11AAAAE--//AAA d+++E"""PPEPPP@@@@@@@666r>   c                     t          j        d |                                 D                       }t          j        |          S )z
        The convex hull of the whole scene.

        Returns
        ---------
        hull : trimesh.Trimesh
          Trimesh object which is a convex hull of all meshes in scene
        c                     g | ]	}|j         
S r   )r   )rS   r   s     r<   rU   z%Scene.convex_hull.<locals>.<listcomp>  s    #D#D#D1AJ#D#D#Dr>   )r   vstack_emptyr   r   convex_hull)r;   r   s     r<   ra  zScene.convex_hull  s<     "#D#D		#D#D#DEE!&)))r>   c                 ,    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_typer   )r   export_scene)r;   rc  rd  kwargss       r<   r   zScene.export  s2    " " 
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	resizabler   )viewer.windowedrh  )r;   r  rf  rh  s       r<   
save_imagezScene.save_image  sE      	322222| 
:%5
 
TZ
 
 	
r>   c                     d | j                                         D             }t          |          dk    r|                                S t          |          dk    rt	          j        d| d           dS )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
        c                     h | ]	}|j         
S r   )r   )rS   r   s     r<   r   zScene.units.<locals>.<setcomp>=  s    <<<AG<<<r>   r!   zMixed units `z` returning NoneN)r(   r|   rh   rs   r   warning)r;   rm   s     r<   r   zScene.units0  sv     =<T]%9%9%;%;<<<x==A<<>>!]]QKBBBBCCCtr>   rT   c                     |                                                                 }| j                                        D ]	}||_        
dS )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(   r|   r   )r;   rT   r   s      r<   r   zScene.unitsD  sM     ##%%%%'' 	 	AAGG	 	r>   desiredguessc                    t          | j                  dk    r|                                 S | j        }|t          j        | |          }t          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   N)rt  )rH  rs  )r   )rh   r(   r   r   units_from_metadataunit_conversionscaled)r;   rs  rt  rH  r   rG  s         r<   convert_unitszScene.convert_unitsS  s    * t}""99;;*? /EBBBG %gwGG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  }nEt          j
        |          dk    rt          j        |||z
            }||z  }nt          d          |                                }	|	dddfxx         |z  cc<   |	| j        |<   dS )	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   r   )r   zexplode vector wrong shape!)r   r   rF   
asanyarrayr   r+   r   r(   rG   r   r   
ValueErrorr   )
r;   vectororiginrM   rH   r   r   offset	projectedT_news
             r<   explodezScene.explode|  sS    >]F>Z$&FvRZ888vRZ8882 	* 	*I'+z)'<$I}}]3<Hvi8Q)?)?@@!DH|r!!"V+v5&!!T))F6Hv,=??	)+ !>??? NN$$E"1"a%LLLF"LLL$)DJy!!%	* 	*r>   r   c                 8   |                                  }t          j        |d          r|S t          |t          t
          t          j        f          ot          |          dk    }|rHt          j        t          j	        |          |d         k              rt          |d                   }d}n|st          |          }|r|j        j        D ]}|j        j        |         }t          |          dk    r|j        |         }|D ]}|j        j        j        |         }|                    |                                 ||||j        j        j        ||f                             dd          |j        j        j        ||f                             dd          	           |                    |           |j        D ]J}|j        |         j        j        d         d
k    r'|j        |                                         |j        |<   K|j        j        D ]}	|j                            |	          \  }
}|
                                 }
d|
dddf<   |j        |                             |
                              |                              t          j                            |
                     |j        j        j        }|D ]n}d||         v rb||         }||         d                                          }
|
dddfxx         |z  cc<   |
|d<    |j        j        d|d         |d         d| oi |j        j        _        t=          t?          j                               |j        j        _!        |j        j        "                                 nt          j#        d          |z  }t          j#        d          |z  }t          j$        | j        j                  }t          j%        t          |          ddf          }dgt          |          z  }tM          |          D ]\  }}| j        |         \  ||<   ||<   |j        "                                 tO          j(        |          D ]}||d                  }||d                  }t          j)        ||          }|j        |         j        j        d         d
k    r!|j        |                             |           n |j        |                             |           tU          ||         ||                   D ]j\  }}
tW          j,        ||
t          j                            |          g          }|dddfxx         |z  cc<   |j                            |||           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!   rC   Nr*   )r(   rN   rM   rO   rH   r*   r   r   )rA   rB   r_   )rB   rC   r(   r   ).r   rF   r8  r8   r   tuplendarrayrh   rC  asarrayr   r+   geometry_nodesr(   rD   parentsr7   	edge_datar   rv   r   r   r=  r   rL   apply_scalelinalginvr:   r6   rg   uuiduuid4	_modifiedrd   rk   r   r   	enumerater   grouprG   r3  r   	multi_dotr  )r;   r   rG  scale_is_3DrN   nodes_with_geomgeomr   pkeyr   r  uvpropsscale_2Dscale_3DrT  rD   
geometriesr   r  r  r(   originalnew_geomrH   s                             r<   rx  zScene.scaled  s     ;uc"" 	M !ubj(ABBVs5zzUV 	!26"*U"3"3uQx"?@@ 	!%(OOEKK 	!%LLE  `	 $\8 6 6	"(,"=i"H''!++!?95D,  "L3;A>++%)YY[[&/&'-.&,l&=&GA&O&S&S ($' ' &,\%<%F1v%N%R%R *D& & ,     **9555 $_ T T	?9-6<Q?1DD171K1Q1Q1S1SFOI.|2 	4 	4%|//449FFHH"1"a% 	*::1==II !/")--"2"23333 /9I S Sy},,%bME!"h/4466Abqb!eHHH%HHH&'E(O'FL'R2a52a5RRERRR-/FL#*03DJLL0A0AFL#-L%%'''' vayy5(Hvayy5(H HTZ677E3u::q!"455J#e**,J %U++ @ @4/3z$/?,
1z!}} L   !
33  %eAh/%eAh/6(H55?8,5;A>!CCOH-==hGGGG OH-==hGGG"5<E1BCC  GD! $!RY]]8=T=T/U V VIbqb!e$$$-$$$L''!%i( (     r>   c                 4   d | j                                         D             }t          | d          r| j        d}n| j                                        }t          || j                                        | j                                        |          }|S )z
        Return a deep copy of the current scene

        Returns
        ----------
        copied : trimesh.Scene
          Copy of the current scene
        c                 >    i | ]\  }}||                                 S r   r   r   s      r<   rY   zScene.copy.<locals>.<dictcomp>6  s&    BBBDAqAqvvxxBBBr>   r  N)r(   r+   r*   r,   )	r(   rc   r   r  r,   r   r&   r+   r*   )r;   r(   r,   copieds       r<   r   z
Scene.copy+  s     CBDM,?,?,A,ABBBtY'' 	(4<+?FF [%%''F*//##]''))	
 
 
 r>   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
        Nr   )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  callabler|  )r;   r  rf  r  r  r  r  s          r<   showz
Scene.showG  s   * >,,,,,, ![]]F T>> -,,,,,;t..v...y  222222$$T44V444x555555''77777f 	 6$))&)))\  r>   c                 B    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)   )r;   otherrG  s      r<   __add__zScene.__add__|  s'     e}dj6K5LMMMr>   )Nr'   NNNNN)NNNNN)ro   N)NNN)r  )F)ro   rJ  )NNrr   )ro   r&   )P__name__
__module____qualname____doc__r   GeometryInputrg   r   r$   r"   r  r   r#   Lightr   r=   rL   r7   r   rt   rv   r   r   r   r   r  r5   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   rN  rP  r]  ra  r   bytesrl  r   ry  r  rx  r   r   r  r  r   r>   r<   r&   r&   '   s         -1!#'&*+/59.299 99=)99 99 4.	99
 
#99 (99 (.1299 #7+99 99 99 99v  & $(#'*.'+#'p pp C=p C=	p
 #3-p G$p 4.p p p pd:U3X+=%> :4 : : : :(	> 	> 	> 	> '+(,(,	& &(#& W%& W%	&
 
& & & &<D# D D D D$ 
'$ 
' 
' 
' X
' 7$ 7 7 7 X7* *S''*:%: ; * * * *X V!12 V V V V" 3''"23 3 3 3 3 0u 0 0 0 0 (77#34     !DW !D !D !D !DF 
 
 
F F F  
e 
 
 
 
" 
 
 
 
 
" 877+ 8 8 8 8@ 
- 
- 
- 	Td38n 	T 	T 	T 	T 1 1 1 1 1 ()d3i () () () ()TJ JH J J J J J< MQ1 1	1 1 1 1f 	/ 	/ X	/ 	.y 	. 	. 	. 	.(U77#3WW5Ewu~#UV ( ( ( (6     X$ ]Xgn5    ] ED E E E XE X^,    X( ]	Xhn5 	 	 	 ]	) ) ) ).8 8 8h 8 8 8 8tT T T T -X - - - -S W    < 
* 
* 
*
 
 
 
*
 
u 
 
 
 
, x}    X& \3    \' 'S ' '' ' ' ' 'R%* %* %* %* %*NFE(I"56 F7 F F F FP   < "3 33 3 3 3j    r>   r&   c                 n   t          | t                    r| S i t          j        |           r?fd| D              t          |           }t	          d | D             d          |_        nGt           | j        di |t          | j                            }t          | j	                  |_        |S )z
    Given a geometry, list of geometries, or a Scene
    return them as a single Scene object.

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

    Returns
    ---------
    scene: trimesh.Scene
    c           	      X    g | ]&}                     t          |d i                     'S r*   )r:   getattr)rS   r   r*   s     r<   rU   zsplit_scene.<locals>.<listcomp>  s1    GGGJ33	4	4GGGr>   r  c              3   2   K   | ]}|j         	|j         V  d S rr   )re   r   s     r<   r   zsplit_scene.<locals>.<genexpr>  s+      QQ1AH<Pah<P<P<P<PQQr>   Nr   )
r8   r&   r   rb   next_sourcesplitr   r*   re   )r(   rf  r   r*   s      @r<   split_scener    s     (E""  H !! 2GGGGhGGGGh222QQQQQSWXX HN$$V$$h/00
 
 
 !11Lr>   r'   c                    t          | t                    r| S |gi }g }t                    t                      fd}| D ]@}t          |d          r|                                }t          |t                    s$t          t          |          j         d          i }|j        	                                D ]2\  }}	t          ||                                          }
|
||<   |	||
<   3i t                      |j                                        D ]S\  }}} ||           ||          }}d|v r|d         |v r||d                  |d<   |                    |||f           T                               Bt          |          }|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
    Nc                     | v r|          S | vr!| v r| t          j                    z   }|| <   |}                     |            | 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  rZ   r  consumedrH  map_nodes     r<   
node_remapz!append_scenes.<locals>.node_remap  sj      8D>! v$("2"2$.***D!HTND 	Dr>   r   z is not a scene!r\   r(   r0   )r8   r&   rt   r   r   r|  typer  r(   rc   r    ri   r+   rY  r   r:   rZ  )iterabler  r)   r(   r[  r  smap_geomrW   rX   rZ   abattrrG  r  rH  r  s    `             @@@r<   r  r    s   $ (E"" ~ HE [[FuuH       B  $! $!1g 			A!U## 	DQ 0BBBCCC J$$&& 	 	DAqQAAADHQKHTNN %%'--// 	' 	'JAq$:a==**Q--qA T!!d:&6(&B&B#+D,<#=Z LL!Q&&&&     j)))F
Lu%%%
O8$$$Mr>   ư>r   r  ro   c           	         | j                                         }| j        D ]}t          |          dk     r|d         }| j         |         \  }}| j        |         j                            t          j                  }|dd         D ]}| j         |         \  }	}
| j        |
         j                            t          j                  }|j	        |j	        k    rRt          ||ddd          \  }}}||k     r+|                    |t          j        |	|          |           t          |j                                                  t!          fd	| j                                        D             |
          S )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)rC   r(   c                 H    i | ]\  }}|v 	||                                 S r   r  )rS   rW   rX   r   s      r<   rY   z)reconstruct_instances.<locals>.<dictcomp>f  s,    TTT$!QAOO!QVVXXOOOr>   rW  )r+   r   r  rh   r(   r   viewrF   r  r   r   r:   rG   rt   r  ri   r&   rc   )r   r  r+   r  	node_baser   	geom_baserI   r  node_mat	node_geomnode_verticesrC   _pcostr   s                  @r<   r  r  $  s   8 KE& X Xu::>> !H	{9-9y1:??
KK!""I 	X 	XD"'+d"3Hi "N95>CCBJOOM "dj00  *mUu     FB n$$T"&6*B*BYWWW#	X( U)..0011J TTTT%.*>*>*@*@TTT   r>   )Nr'   )r  )4r2   r  rD  r   r   hashlibr   numpyrF   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   r   r    r"   r#   rD   r$   rg   r  r&   r  r  r  r   r>   r<   <module>r     sx                         O O O O O O O O O O O O O O O O O O             ) ) ) ) ) ) ) ) % % % % % %                                               " " " " " " h 2Dh4GRSd d d d dJ d d dN+" " "Jn n n nbD D D DE D D D D D Dr>   