
    Mi                     ^   S SK r S SKrS SKrS SKJr  S SKJr  S SKrSSK	J
r
JrJrJrJrJrJr  SSKJr  SSKJr  SSKJrJr  SS	KJr  SS
KJrJrJrJrJrJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(  SSKJ)r)  SSK	J*r*J+r+  SSK,J-r-  \%\\\   \\.\4   \4   r/ " S S\5      r0S r1SS jr2SS\0S\S\04S jjr3g)    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                   *   \ rS rSrSr       SPS\\   S\S\\   S\\	   S\\
R                     S	\\\R                        S
\\   4S jjrS r     SQS\S\\   S\\   S\\   S\\   S\\   4S jjrS\\\\4   SS4S jrSRS jr   SSS\\   S\\   S\\   SS4S jjrS\4S jr\S\4S j5       r\S\4S j5       r\ RB                  S\\\\"   4   4S j5       r#\ RB                  S\\\"      4S j5       r$\ RB                  S\\\"      4S j5       r%\ RB                  S\&4S  j5       r'\ RB                  S\\\"      4S! j5       r(\ RB                  S\4S" j5       r)\ RB                  S# 5       r*S$ r+\ RB                  S\&4S% j5       r,\ RB                  S\"4S& j5       r-\ RB                  S\\"   4S' j5       r.\ RB                  S( 5       r/\ RB                  S\\\4   4S) j5       r0\ RB                  S\4S* j5       r1\ RB                  S\2\2\      4S+ j5       r3STS,\SS 4S- jjr4 SQS\
R                  4S. jjr5\S/ 5       r6\6Rn                  S0\84S1 j5       r6S\9\\"   \\"   \\:   4   4S2 jr;\S\
R                  4S3 j5       r<\<Rn                  S\\
R                     4S4 j5       r<\S\4S5 j5       r=\S\2\R                     4S6 j5       r>\>Rn                  S	\\R                     4S7 j5       r>SRS8 jr?SUS9\S\2\@   4S: jjrASVS; jrBS\@4S< jrCS=\SS 4S> jrD\ RB                  S? 5       rESWS@ jrFSXS\G4SA jjrH\S\\   4SB j5       rI\IRn                  SC\4SD j5       rISUSE\SF\SS 4SG jjrJSWSRSH jjrKSI\\\84   SS 4SJ jrLSYSK jrM SXSL\N4SM jjrOSN rPSOrQg)ZScene'   z
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                 |   [         R                  " 5       U l        [        US9U l        [
        R                  " U R                  S9U l        Ub  U R                  U5        0 U l
        [        U[        5      (       a  U R                  R                  U5        Ub  X@l        Ub  X`l        Ub  XPl        Ub  Xpl        ggg)a  
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/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/site-packages/trimesh/scene/scene.py__init__Scene.__init__/   s    > $//1  :6
 mm>h' h%%MM  *J K K+(8% ,     c                    U R                   R                  nU R                   R                  R                  U    HC  n[        R
                  " XR                   U   S   5      nU R                   R                  X#US9  ME     U $ )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_transformScene.apply_transformj   sl     zz$$ZZ**33D9EvviE):1)=>HJJhO : r?   	node_name	geom_nameparent_node_namerI   c                 p   Uc  g[         R                  " U5      (       a%  U Vs/ s H  nU R                  UUUUUUS9PM     sn$ [        U[        5      (       a3  UR                  5        VV	s0 s H  u  pXR                  XUS9_M     sn	n$ [        U[        5      (       ai  X-   n
U R                  R                  5         U R                  R                  U
R                  5        U
R                  R                  U R                  l        gUb  UnOoSUR                  ;   a  UR                  S   nOOUR                  R                  b  UR                  R                  nO!S[        [!        U R                  5      5      -   n[#        XR                  R%                  5       S9nXR                  U'   Uc@  U R                  R                  R&                  R%                  5       n[#        X5      nX,;  d   eUc  [(        R*                  " S5      nU R                  R                  UUUUSS	0US
9  U$ s  snf s  sn	nf )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(   rO   rP   rQ   rI   r*   )r(   rP   r*   name	geometry_startcontains   visibleT)rC   rB   rD   r(   geometry_flagsr*   )r   is_sequencer7   r8   r9   itemsr&   r(   clearr:   r+   rE   r*   source	file_namestrlenr    keys	node_datarG   eye)r;   r(   rO   rP   rQ   rI   r*   valuekvconcatrS   existings                r<   r7   Scene.add_geometryz   s&   L h'' &
 &E !!"''%5'% "  &
 
 $'' %NN,,DA $$ax$PP, 
 %((_FMM!MM  1$*LL$;$;DJJ!  Dx((($$V,D__&&2??,,D S%7!88D 0B0B0DE&d  zz,,66;;=H $D3I,,,q	I

'%t, 	 	
 K
s   H--H2namesreturnc                     [        U[        5      (       a  U/n[        U5      nU R                  R	                  U5        U Vs/ s H  o R
                  R                  US5      PM        ngs  snf )z
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)r8   r`   setr+   remove_geometriesr(   pop)r;   rk   rS   s      r<   delete_geometryScene.delete_geometry   sY     eS!!GEE
 	

$$U+38954		4	&599s   %A+c                     SSK Jn  U R                  R                  5        H,  n[        R
                  " US5      (       d  M!  U" US9Ul        M.     g)zT
Strip visuals from every Trimesh geometry
and set them to an empty `ColorVisuals`.
r   )ColorVisualsTrimesh)meshN)visual.colorrt   r(   valuesr   is_instance_namedvisual)r;   rt   r(   s      r<   strip_visualsScene.strip_visuals   s=    
 	0,,.H%%h	::".H"= /r?   percent
face_count
aggressionc                     0 nU R                   R                  5        H*  u  pV[        US5      (       d  M  UR                  XUS9XE'   M,     U R                   R	                  U5        g)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(   r\   hasattrr   r:   )r;   r}   r~   r   updatesrf   rg   s          r<   r   !Scene.simplify_quadric_decimation  s`    , MM'')DAq788::#z ; 
 *
 	W%r?   c                 2  ^ U R                   m[        U R                  R                  R	                  5       5      /nUR                  U4S jTR                  5        5       5        [        R                  " SR                  U5      R                  S5      5      $ )ze
Return information about scene which is hashable.

Returns
---------
hashed
  String hashing scene.
c              3   \   >#    U  H!  n[        TU   R                  5       5      v   M#     g 7fN)hexr5   ).0rf   r(   s     r<   	<genexpr>!Scene.__hash__.<locals>.<genexpr>8  s&     M_HQK00233_s   ), zutf-8)r(   r   r+   rE   r5   extendrb   r   	hash_fastjoinencode)r;   hashabler(   s     @r<   r5   Scene.__hash__)  sm     == 

--6689:MX]]_MM  !2!9!9'!BCCr?   c                 2    [        U R                  5      S:H  $ )zd
Does the scene have anything in it.

Returns
----------
is_empty
  True if nothing is in the scene
r   )ra   r(   r;   s    r<   is_emptyScene.is_empty;  s     4==!Q&&r?   c                    [        U R                  5      S:X  a  g U R                  R                   Vs1 s H  oR                  U   S   iM     nnU[        U R                  R                  5       5      :H  $ s  snf ! [         a     gf = f)z{
Is every geometry connected to the root node.

Returns
-----------
is_valid : bool
  Does every geometry have a transform
r   Tr!   F)ra   r(   r+   nodes_geometryBaseExceptionrn   rb   )r;   i
referenceds      r<   is_validScene.is_validH  s     t}}"	48JJ4M4MN4Mq**Q-*4MJN S!3!3!5666 O 		s"   A< A7A< 7A< <
B	B	c                 p   0 nU R                   R                  5        VVs0 s HH  u  p#U[        US5      (       a%  [        UR                  5      S:  a  UR                  OUR
                  _MJ     nnnUR                  UR                  5        VVs0 s HU  u  p%Uc  M
  UR                  S   S:X  d  M  U[        R                  " U[        R                  " [        U5      5      45      _MW     snn5        U R                  R                   H  nU R                  U   u  pxUR                  U5      n	U	c  M*  [        R                  " USS2SS24   U	R                  5      n
[        R                   " U
R#                  SS9USS2S4   -   U
R%                  SS9USS2S4   -   /5      X'   M     U$ s  snnf s  snnf )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(   r\   r   ra   r   boundsr:   shaperG   column_stackzerosr+   r   getrH   Tarrayminmax)r;   cornersrf   mr   rg   rO   rI   geometry_namepointsrH   s              r<   bounds_cornersScene.bounds_corners^  s     ++-
- WQ
33AJJ!8KqzzQRQYQYY- 	 

 	 %NN,,DA :%&WWQZ1_ :2??ArxxA'7#899,	
 22I'+zz)'<$I\\-0F~&&2A2rr6*FHH5C!#a9RaRU#33SWW!W_yQSRSQSUVQVGW5WX"G 3 9
s   AF,	F2
F2
2:F2
c                 &   U R                   n[        U5      S:X  a  g[        R                  " [	        U R                   R                  5       5      5      n[        R                  " UR                  SS9UR                  SS9/[        R                  S9$ )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   ra   rG   vstacklistrx   r   r   r   r   )r;   r   r   s      r<   r   Scene.bounds  sq     ,,~!#))D!4!4!;!;!=>?xx!,gkkqk.AB"**UUr?   c                 j    U R                   nUc  g[        R                  " USS9R                  S5      $ )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   rG   diffreshape)r;   r   s     r<   extentsScene.extents  s1     >wwvA&..r22r?   c                 `    U R                   nUc  g[        US-  R                  5       S-  5      $ )zr
The approximate scale of the mesh

Returns
-----------
scale : float
  The mean of the bounding box edge lengths
      ?r   g      ?)r   floatsum)r;   r   s     r<   scaleScene.scale  s2     ,,?gqj%%'3.//r?   c                 d    U R                   nUc  g[        R                  " U R                   SS9nU$ )z
Return the center of the bounding box for the scene.

Returns
--------
centroid : (3) float
  Point for center of bounding box
Nr   r   )r   rG   mean)r;   r   centroids      r<   r   Scene.centroid  s.     >774;;Q/r?   c                 p   U R                   R                  5        VVs0 s H$  u  p[        US5      (       d  M  XR                  _M&     nnnU R                   R                  5        VVs0 s H$  u  p[        US5      (       d  M  XR                  _M&     nnnU R
                  nUR                   Vs/ s H  oeU   PM	     nn[        R                  " U VV	s/ s H=  u  pX;   d  M  [        R                  " U[        R                  " X9   S5      5      SS PM?     sn	n[        R                  S9n
[        R                  " U VV	s/ s H	  u  pXI   PM     sn	n[        R                  S9nXR                  5       -  nXR                  S5      -  R                  SS	9$ s  snnf s  snnf s  snf s  sn	nf s  sn	nf )
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(   r\   r   r   r   r+   r   rG   r   rH   appendr   r   r   )r;   rf   r   r   r   r+   ninstancematgtransformed_weightss                r<   r   Scene.center_mass  sw    ++-
-q-( A}}- 	 

 '+mm&9&9&;R&;dawq&?Q	66	&;R 

&+&:&:;&:!H&:; hh '&FC# >sBIIkna89"1=&
 **
 ((9DG9L;;= oog66;;;CC/

 S < :s.   FF)F!F!1F'F,
%5F,
F2
c                 h    [         R                  " U [        R                  " U R                  5      S9$ )z
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`
scenerI   )r	   scene_inertiar
   translation_matrixr   r   s    r<   moment_inertiaScene.moment_inertia  s-     $$/"D"DTEUEU"V
 	
r?   c                 *    [         R                  " XS9$ )z
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;   rI   s     r<   moment_inertia_frameScene.moment_inertia_frame  s     $$4EEr?   c                    ^ ^ T R                   R                  5        VVs0 s H$  u  p[        US5      (       d  M  XR                  _M&     snnm[	        UU 4S jT R
                  R                   5       S5      $ s  snnf )z
What is the summed area of every geometry which
has area.

Returns
------------
area : float
  Summed area of every instanced geometry
areac              3   h   >#    U  H'  nTR                  TR                  U   S    S5      v   M)     g7fr!           Nr   r+   )r   r   areasr;   s     r<   r   Scene.area.<locals>.<genexpr>  s.     Q7P!UYYtzz!}Q'--7P   /2r   )r(   r\   r   r   r   r+   r   )r;   r   r   r   s   `  @r<   r   
Scene.area  sc     (,}}':':'<S'<tq6@RFF'<SQtzz7P7PQSV
 	
 T
   A:A:c                    ^ ^ T R                   R                  5        VVs0 s H$  u  p[        US5      (       d  M  XR                  _M&     snnm[	        U U4S jT R
                  R                   5       S5      $ s  snnf )z
What is the summed volume of every geometry which
has volume

Returns
------------
volume : float
  Summed area of every instanced geometry
r   c              3   h   >#    U  H'  nTR                  TR                  U   S    S5      v   M)     g7fr   r   )r   r   r;   volumes     r<   r   Scene.volume.<locals>.<genexpr>0  s.     R8Q1VZZ

1a(#..8Qr   r   )r(   r\   r   r   r   r+   r   )r;   r   r   r   s   `  @r<   r   Scene.volume!  sc     +/--*=*=*?V*?$!71fCU+!XX+*?VR

8Q8QRTW
 	
 Wr   c           	      B   / n/ nU R                   R                   H  nU R                   U   u  pEU R                  U   n[        US5      (       d  M6  UR	                  [
        R                  " UR                  R                  5       R                  S5      US95        UR	                  [        R                  " U[        UR                  5      5      5        M     [        R                  " U5      U R                  S'   [        R                  " U5      R                  S5      $ )z
Return a correctly transformed polygon soup of the
current scene.

Returns
----------
triangles : (n, 3, 3) float
  Triangles in space
	triangles)r   r   )rD   triangles_node)r   r   r   )r+   r   r(   r   r   r
   transform_pointsr   copyr   rG   tilera   hstackr6   r   )r;   r   r   rO   rI   r   r(   s          r<   r   Scene.triangles3  s     	22I'+zz)'<$I }}]3H8[1100&&++-55g>y !!"'')S9K9K5L"MN 3" )+		.(A$%yy#++J77r?   c                 8    U R                   nU R                  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   Scene.triangles_nodeT  s     >>{{+,,r?   c                     U R                   R                  5        VVs0 s H  u  pUR                  U_M     snn$ s  snnf )zq
Look up geometries by identifier hash.

Returns
---------
identifiers
  {Identifier hash: key in self.geometry}
)r(   r\   identifier_hash)r;   rS   rv   s      r<   geometry_identifiersScene.geometry_identifiersa  s9     >B]]=P=P=RS=Rzt$$d*=RSSSs   ;c                     SR                  S U R                  R                  5        5       5      [        [	        U R
                  5      5      -   n[        UR                  5       5      R                  5       $ )z(
Get a unique identifier for the scene.
r   c              3   8   #    U  H  oR                   v   M     g 7fr   )r   r   r   s     r<   r   (Scene.identifier_hash.<locals>.<genexpr>r  s     I2HQ((2Hs   )	r   r(   rx   r`   hashr+   r   r   	hexdigest)r;   dumps     r<   r   Scene.identifier_hashm  sZ    
 wwI$--2F2F2HIICM
 
 dkkm$..00r?   c           	      X   [        U R                  5      S:X  a  / $ U R                  R                  5        VVs0 s H/  u  p[        US5      (       d  M  U[	        UR
                  S5      _M1     nnnU R                  nUR                   Vs0 s H  oUUR                  XE   S   5      _M     nn[        R                  " [        5      nUR                  5        VVs/ s H  u  pXUc  M
  Xx   R                  U5      PM       nn[        UR                  5       5      $ s  snnf s  snf s  snnf )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!   )ra   r(   r\   r   intr   r+   r   r   r2   defaultdictr   r   rx   )	r;   rf   r   hashesr+   node	node_hash
duplicateshasheds	            r<   duplicate_nodesScene.duplicate_nodesw  s    t}}"I
 ++-
-q+, *As1$$b))- 	 
 

 CHBVBVWBV$6::ek!n55BV	W !,,T2

 !* 1	
 1 ,J%%d+ 1	
 J%%'((/
 X	
s   DD D!	D&(D&cost_thresholdc                     [        XS9$ )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  Scene.reconstruct_instances  s    6 %TIIr?   c                    Uc  [         R                  " SS/5      n[        U R                  5      S:X  a\  [        R
                  " US9U l        [         R                  " S5      U R                  U R                  R                  '   U R                  $ Uc  [         R                  " S5      n[        R                  " U6 n[        R                  " U R                  XVX#S9n[        U S5      (       a1  U R                  b$  XPR                  l        Ub  X@R                  l        O[        R
                  " XTS	9U l        XpR                  U R                  R                  '   U R                  $ )
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   )fovrX   r   )r  rotationdistancecenter_camera)r  
resolution)rG   r   ra   r(   r"   Camerar  rd   r+   rS   r   r
   euler_matrixlook_atr   r   r  r  )r;   anglesr  r  r  r  r  rI   s           r<   
set_cameraScene.set_camera  s   , ;((B8$C t}}"">>c2DL,.FF1IDJJt||(()<<>XXa[F"//8OOKKSh
	 4##(@"LL%*4' #>>cIDL(1

4<<$$%||r?   c                 N    U R                   U R                  R                     S   $ )z
Get camera transform in the base frame.

Returns
-------
camera_transform : (4, 4) float
  Camera transform in the base frame
r   r+   r,   rS   r   s    r<   r.   Scene.camera_transform  s"     zz$++**+A..r?   rD   c                 H    XR                   U R                  R                  '   g)z
Set the camera transform in the base frame

Parameters
----------
camera_transform : (4, 4) float
  Camera transform in the base frame
Nr$  )r;   rD   s     r<   r.   r%    s     (.

4;;##$r?   c                     U R                   R                  5       u  pU R                  n[        R                  " XSS9n[
        R                  " U5      [        R                  " U5      -  nXAU4$ )aR  
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   rG   	ones_liketranslation_from_matrix)r;   vectorspixelsrI   originss        r<   camera_raysScene.camera_rays
  sf      ++--/))	!227QVW,,w'/*Q*Q+
 
 ''r?   c                 z    U R                   (       d  U R                  5       $ U R                  c   eU R                  $ )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,   Scene.camera%  s2     ??$$||'''||r?   c                     Uc  gXl         g)zx
Set a camera object for the Scene.

Parameters
-----------
camera : trimesh.scene.Camera
  Camera object for the scene
N)r  )r;   r,   s     r<   r,   r3  8  s     >r?   c                 D    [        U S5      =(       a    U R                  S L$ )Nr  )r   r  r   s    r<   r2  Scene.has_cameraF  s    tY'DDLL,DDr?   c                     [        U S5      (       a  U R                  cJ  [        R                  " U 5      u  p[	        X5       H  u  p4X@R
                  UR                  '   M     Xl        U R                  $ )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   r8  r#   	autolightzipr+   rS   )r;   r-   rE   Lr   s        r<   r-   Scene.lightsJ  s_     tY''4<<+?!)!3!3D!9FF/%&

166" 0 "L||r?   c                     Xl         g)z
Assign a list of light objects to the scene

Parameters
--------------
lights : [trimesh.scene.lighting.Light]
  Lights in the scene.
N)r8  )r;   r-   s     r<   r-   r<  _  s	     r?   c                    U R                   (       d&  [        R                  " U R                  S5      (       a  g[        R                  " S5      nU R                  * USS2S4'   [        U R                  R                  5      S-   nU R                  R                  X R                  R                  US9  X R                  l        g)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   NrX   r   _IrA   )	r   rG   allcloser   rd   r`   r+   r)   r:   )r;   rD   new_bases      r<   rezeroScene.rezerok  s     ==BKKs;; rr1u tzz,,-4

***?*? 	 	
 !)

r?   concatenatec                 l   / nU R                   R                   H  nU R                   U   u  pEU R                  U   R                  5       n[	        US5      (       a`  [
        R                  " U[
        R                  SS9nSUSS2SS24'   UR                  5       (       d  UR                  5       nOUSS2SS24   nUR                  U5        XVR                  S'   X6R                  S	'   UR                  U5        M     U(       a0  [        R                  " S
[        SS9  [
        R                   " U5      $ U$ )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   rS   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allrF  rM   r*   r   warningswarnDeprecationWarningrD  )r;   rD  resultrO   rI   r   currentchecks           r<   r  
Scene.dump  s   * 22I'+zz)'<$ImmM2779G w((YTJ $bqb"1"fyy{{%mmoG !*"1"bqb& 1I ##I.'4V$'0V$ MM'"/ 32 MMv+ ##F++r?   c           	          SSK Jn  [        R                  " U R	                  5        Vs/ s H  n[        X!5      (       d  M  UPM     sn5      $ s  snf )z
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   )ru   )rJ   ru   r   rD  r  r8   )r;   ru   ds      r<   to_meshScene.to_mesh  s9     	# DIIK RKq:a;QK RSS Rs   AAc                 J    [         R                  " U R                  5       5      $ )a  
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   rD  r  r   s    r<   to_geometryScene.to_geometry  s     		,,r?   r
  c                    U R                   nUR                  R                  U5      nUR                  5        Vs/ s H  oDS   U;   d  M  UPM     nn[	        US9nUR                  U5        U Vs1 s H  nSUS   ;   d  M  US   S   iM     nnU Vs0 s H  owU R                  U   _M     nn[        XS9n	U	$ s  snf s  snf s  snf )z
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   r0   r(   r   r(   r+   )r+   rE   
successorsto_edgelistr$   from_edgelistr(   r&   )
r;   r
  r+   nodeseedgesgeometry_namesrf   r(   rP  s
             r<   subsceneScene.subscene  s      

  ++D1!--/A/qQ45=/A d+E"49PEqZ1Q4=O*!A$z*EP1?@At}}Q''@6 B Q@s   B9
B90B>B>Cc                     [         R                  " U R                  5        Vs/ s H  oR                  PM     sn5      n[        R
                  " U5      $ s  snf )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)r;   r   r   s      r<   rh  Scene.convex_hull  sB     ""		#D1JJ#DE!!&)) $Es   Ac                 4    [         R                  " SXUS.UD6$ )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)r;   rk  rl  kwargss       r<   r   Scene.export  s)    " "" 
Y
BH
 	
r?   c                 &    SSK Jn  U" SXSSS.UD6$ )z
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	resizablerm  )viewer.windowedrr  )r;   r  ro  rr  s       r<   
save_imageScene.save_image  s(      	3 
%5
TZ
 	
r?   c                    U R                   R                  5        Vs1 s H  oR                  iM     nn[        U5      S:X  a  UR	                  5       $ [        U5      S:  a  [
        R                  " SU S35        gs  snf )z
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(   rx   r   ra   rp   r   warning)r;   r   ri   s      r<   r   Scene.units0  sk     &*]]%9%9%;<%;GG%;<x=A<<>!]QKK-z1ABC =s   A=re   c                     UR                  5       R                  5       nU R                  R                  5        H	  nXl        M     g)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(   rx   r   )r;   re   r   s      r<   r   rz  D  s4     ##%%%'AG (r?   desiredguessc                     [        U R                  5      S:X  a  U R                  5       $ U R                  nUc  [        R                  " XS9n[        R
                  " X1S9nU R                  US9nXl        U$ )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   )r  )rQ  r~  )r   )ra   r(   r   r   units_from_metadataunit_conversionscaled)r;   r~  r  rQ  r   rP  s         r<   convert_unitsScene.convert_unitsS  sq    * t}}"99;**? //BG %%gG 5) r?   c                    Uc  U R                   nUc  U R                  S-  n[        R                  " U[        R                  S9n[        R                  " U[        R                  S9nU R
                  R                   H  nU R
                  U   u  pEU R                  U   R                   n[        R                  " U[        R                  " US5      5      SS nUR                  S:X  a  Xb-
  U-  nOC[        R                  " U5      S:X  a  [        R                  " XU-
  5      nX-  nO[        S5      eUR                  5       n	U	SS2S4==   U-  ss'   XR
                  U'   M     g)	z
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   rm  )r   zexplode vector wrong shape!)r   r   rG   
asanyarrayr   r+   r   r(   rH   r   r   
ValueErrorr   )
r;   vectororiginrO   rI   r   r   offset	projectedT_news
             r<   explodeScene.explode|  s)    >]]F>ZZ$&FvRZZ8vRZZ822I'+zz)'<$I}}]3<<Hvvi8Q)?@!DH||r!"+v5&!T)FF6v,=?	+ !>?? NN$E"1"a%LF"L$)JJy!% 3r?   r   c                 
   U R                  5       n[        R                  " US5      (       a  U$ [        U[        [
        [        R                  45      =(       a    [        U5      S:H  nU(       aF  [        R                  " [        R                  " U5      US   :H  5      (       a  [        US   5      nSnOU(       d  [        U5      nU(       Ga.  UR                  R                   GH   nUR                  R                  U   n[        U5      S:  d  M.  UR                  U   nU H  nUR                  R                  R                  U   nUR!                  UR                  5       UUUUR                  R                  R"                  X4   R%                  SS5      UR                  R                  R"                  X4   R%                  SS5      S	9  M     UR'                  U5        GM     UR                   HY  nUR                  U   R(                  R*                  S   S
:X  d  M/  UR                  U   R-                  5       UR                  U'   M[     UR                  R.                   H  n	UR                  R%                  U	5      u  pU
R                  5       n
SU
SS2S4'   UR                  U   R1                  U
5      R3                  U5      R1                  [        R4                  R7                  U
5      5        M     UR                  R                  R"                  nU H`  nSX   ;   d  M  X   nX   S   R                  5       n
U
SS2S4==   U-  ss'   XS'   UR                  R8                  " SUS   US   S.UD6  Mb     0 UR                  R                  l        [=        [>        R@                  " 5       5      UR                  R                  l!        UR                  R:                  RE                  5         GO[        RF                  " S5      U-  n[        RF                  " S5      U-  n[        RH                  " U R                  R.                  5      n[        RJ                  " [        U5      SS45      nS/[        U5      -  n[M        U5       H  u  nnU R                  U   u  UU'   UU'   M      UR                  RE                  5         [N        RP                  " U5       GH  nUUS      nUUS      n[        RR                  " UU5      nUR                  U   R(                  R*                  S   S
:X  a  UR                  U   R1                  U5        OUR                  U   R1                  U5        [U        UU   UU   5       Hg  u  nn
[V        RX                  " X[        R4                  R7                  U5      /5      nUSS2S4==   U-  ss'   UR                  R9                  UUUS9  Mi     GM     SUl-        U$ )a  
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!   rD   Nr*   )r(   rP   rO   rQ   rI   r*   r   r   )rB   rC   rX   )rC   rD   r(   rm  ).r   rG   r@  r8   r   tuplendarrayra   rL  asarrayr   r+   geometry_nodesr(   rE   parentsr7   	edge_datar   rq   r   r   rF  r   rM   apply_scalelinalginvr:   r6   r`   uuiduuid4	_modifiedr]   rd   r   r   	enumerater   grouprH   r:  r   	multi_dotr  )r;   r   rP  scale_is_3DrP   nodes_with_geomgeomr   pkeyr   r  uvpropsscale_2Dscale_3Dr`  rE   
geometriesr   r
  r  r(   originalnew_geomrI   s                             r<   r  Scene.scaled  s     ;;uc""M !ubjj(ABVs5zUV266"**U"3uQx"?@@%(OEK%LE  $\\88	"(,,"="=i"H'!+!??95D,"LL33;;A>++%)YY[&/&'-.&,ll&=&=&G&G&O&S&S ($' &,\\%<%<%F%Fv%N%R%R *D& ,  - **95% 9* $__	??9-66<<Q?1D171K1Q1Q1SFOOI. - ||22%||//4FFH"1"a% 	*::1=II!/"))--"23 3 //99Iy},%ME!h/446Abqb!eH%H&'(OLL''R2a52a5RER   .0FLL##*03DJJL0AFLL##-LL%%' vvay5(Hvvay5(H HHTZZ667E3u:q!"45J#e*,J %U+4/3zz$/?,
1z!} , LL !
3%eAh/%eAh/66(H5??8,55;;A>!COOH-==hG OOH-==hG"5<E1BCGD! $RYY]]8=T/U VIbqb!e$-$LL''!%i( (   D 44 r?   c                 x   U R                   R                  5        VVs0 s H  u  pXR                  5       _M     nnn[        U S5      (       a  U R                  c  SnOU R
                  R                  5       n[        UU R                  R                  5       U R                  R                  5       US9nU$ s  snnf )zp
Return a deep copy of the current scene

Returns
----------
copied : trimesh.Scene
  Copy of the current scene
r  N)r(   r+   r*   r,   )	r(   r\   r   r   r  r,   r&   r+   r*   )r;   r   r   r(   r,   copieds         r<   r   
Scene.copy+  s     -1MM,?,?,AB,ADAAvvxK,ABtY''4<<+?F [[%%'F**//#]]'')	
  Cs   B6viewerc                     Uc  SSK Jn  U" 5       nU(       d  SnUS:X  a  SSK Jn  U" U 40 UD6$ US:X  a  SSK Jn  U" U 40 UD6$ US:X  a  SSK Jn  U" U 40 UD6$ [        U5      (       a	  U" U 40 UD6$ [        S	5      e)
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  callabler  )r;   r  ro  r  r  r  r  s          r<   show
Scene.showG  s    * >, !]FT> -t.v..y 2$T4V44x5'777f $)&))\ r?   c                 F    [        X/U R                  R                  /S9nU$ )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;   otherrP  s      r<   __add__Scene.__add__|  s$     }djj6K6K5LMr?   )	r6   r  r8  r,   r.   r(   r+   r-   r*   )NworldNNNNN)NNNNN)rl   N)NNN)gh㈵>)F)rl   ztrimesh.Trimesh)NNr   )rl   r&   )R__name__
__module____qualname____firstlineno____doc__r   GeometryInputr`   r   r$   r"   r  r   r#   Lightr   r=   rM   r7   r   rn   rq   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,   r2  r-   rB  r   r  rV  rY  rd  rh  r   bytesrv  r   r  r  r  r   r   r  r  __static_attributes__rm  r?   r<   r&   r&   '   s    -1!#'&*+/59.299=)99 99 4.	99
 
#99 (99 (..1299 #7+99v& $(#'*.'+#'pp C=p C=	p
 #3-p G$p 4.pd:U3X+=%> :4 :(	> '+(,(,	&(#& W%& W%	&
 
&<D# D$ 
'$ 
' 
' 7$ 7 7* *S''*:%: ; * *X V!12 V V" 3''"23 3 3 0u 0 0 (77#34   !DW !D !DF 
 
F  
e 
 
" 
 
 
" 877+ 8 8@ 
- 
- 	Td38n 	T 	T 1 1 1 ()d3i () ()TJH J J< MQ1	1f 	/ 	/ 	.y 	. 	.(U77#3WW5Ewu~#UV (6   $ ]]Xgnn5   ED E E X^^,  ( ]]	Xhnn5 	 	).8 8h 8tT -X -S W < 
* 
*
*
u 
, x}  & \\3  'S ' '' 'R%*NFE(I"56 F7 FP< "33jr?   r&   c           
         [        U [        5      (       a  U $ 0 n[        R                  " U 5      (       aN  U  Vs/ s H  o2R	                  [        US0 5      5      PM        n[        XS9n[        S U  5       S5      Ul        U$ [        U R                  " S0 UD6[        U R                  5      S9n[        U R                  5      Ul        U$ s  snf )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   V   #    U  H  oR                   c  M  UR                   v   M!     g 7fr   )r^   r   s     r<   r   split_scene.<locals>.<genexpr>  s     Q1HHhahhs   ))Nrm  )r8   r&   r   r[   r:   getattrnext_sourcesplitr   r*   r^   )r(   ro  r*   r   r   s        r<   split_scener    s     (E"" H !!>FGhJ3	4hGh2QQSWX L NN$V$h//0
 !1L 	Hs   %Cc                 N  ^^^^ [        U [        5      (       a  U $ Tc  U/m0 n/ n[        T5      m[        5       mUUUU4S jnU  GH  n[        US5      (       a  UR	                  5       n[        U[        5      (       d!  [        [        U5      R                   S35      e0 nUR                  R                  5        H$  u  p[        XR                  5       S9n
XU'   XU
'   M&     0 m[        5       mUR                  R                  5        HA  u  pnU" U5      U" U5      pSU;   a  US   U;   a
  X}S      US'   UR                  XU45        MC     TR                  T5        GM     [        US9nUR                  R!                  U5        UR                  R                  U5        U$ )aO  
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                    > U T;   a  TU    $ U T;  a%  U T;   a  U [         R                  " 5       -   nUTU '   Un TR                  U 5        U $ )z
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
  rS   r  consumedrQ  map_nodes     r<   
node_remap!append_scenes.<locals>.node_remap  sZ      8D>! v$("2$..**D!HTND 	Dr?   r   z is not a scene!rU   r(   r0   )r8   r&   rn   r   r   r  typer  r(   r\   r    rb   r+   r^  r   r:   r_  )iterabler  r)   r(   rb  r  smap_geomrf   rg   rS   abattrrP  r  rQ  r  s    `             @@@r<   r  r    s   $ (E""~ HE [FuH B 1g	A!U##Q 0 011ABCC JJ$$&DAQADQKTN ' %''--/JA$a=*Q-q T!d:&6(&B#+,<#=Z LL!& 0 	 I N j)F
LLu%
OO8$Mr?   r   r  rl   c           
      ^   U R                   R                  5       nU R                   GH  n[        U5      S:  a  M  US   nU R                   U   u  pVU R                  U   R
                  R                  [        R                  5      nUSS  H  nU R                   U   u  pU R                  U
   R
                  R                  [        R                  5      nUR                  UR                  :w  a  Mf  [        X{SSSS9u  pnX:  d  M|  UR                  U[        R                  " X5      US9  M     GM     [        UR                  R                  5       5      n[!        U R                  R#                  5        VVs0 s H  u  nnUU;   d  M  UUR                  5       _M!     snnUS	9$ s  snnf )
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   r   r!   NTF)translationr   
reflection)rD   r(   r\  )r+   r   r  ra   r(   r   viewrG   r  r   r   r:   rH   rn   r  rb   r&   r\   )r   r  r+   r  	node_baser   	geom_baserJ   r
  node_mat	node_geomnode_verticesrD   _pcostr   rf   rg   s                     r<   r  r  $  st   8 KKE&&u:> !H	{{9-y1::??

K!"ID"'++d"3H "NN95>>CCBJJOM ""djj0  *Uu F $T"&&*BYW#  '@ U))..01J */..*>*>*@T*@$!QAO+!QVVX+*@T Ts   <F)
F)
)Nr  )gư>)4r2   r  rM  r   r   hashlibr   numpyrG   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#   rE   r$   r`   r  r&   r  r  r  rm  r?   r<   <module>r     s          O O O   ) %       " h 2Dh4GRSdJ dN+"JnbD D DE Dr?   