
    Mi[f                        S r SSKrSSKJrJr  SSKJrJrJ	r	J
r
JrJr  SSKJrJr  Sr " S S	5      rS
 rSS jrS rS r       SS jr      SS\S\S\\   S\\   S\\
   S\\   4S jjrS rS rS\S\S\	\   4S jrS S jrg)!zT
packing.py
------------

Pack rectangular regions onto larger rectangular regions.
    N   )logtol)	ArrayLikeIntegerNDArrayNumberOptionalfloat64)allclosebounds_treeg-q=c                   8    \ rS rSrSrS r\S 5       rSS jrSr	g)	RectangleBin   aj  
An N-dimensional binary space partition tree for packing
hyper-rectangles. Split logic is pure `numpy` but behaves
similarly to `scipy.spatial.Rectangle`.

Mostly useful for packing 2D textures and 3D boxes and
has not been tested outside of 2 and 3 dimensions.

Original article about using this for packing textures:
http://www.blackpawn.com/texts/lightmaps/
c                 p    / U l         SU l        [        R                  " U[        R                  S9U l        g)zw
Create a rectangular bin.

Parameters
------------
bounds : (2, dimension *) float
  Bounds array are `[mins, maxes]`
FdtypeN)childoccupiednparrayr   boundsselfr   s     n/var/www/eduai.edurigo.com/storigo/production/storigo_env/lib/python3.13/site-packages/trimesh/path/packing.py__init__RectangleBin.__init__   s(     
hhvRZZ8    c                 0    U R                   nUS   US   -
  $ )zd
Bounding box size.

Returns
----------
extents : (dimension,) float
  Edge lengths of bounding box
   r   r   r   s     r   extentsRectangleBin.extents0   s      ay6!9$$r   c                    U R                    H  nUR                  XS9nUc  M  Us  $    U R                  (       a  gU R                  R	                  5       nUS   US   -
  nU(       a^  [        [        U5      5       H=  nU[        X5      -
  nU[        * :  R                  5       n	U	(       d  M2  [        X5      n  O   W	(       d  gO"Xa-
  nU[        * :  R                  5       (       a  gSU l        W[        :  R                  5       (       a  U$ UR                  5       n
[        R                  " XU45      nUS   U
   X   -   USS2U
4'   [        USS 5      [        USS 5      4U R                   SS& U R                   S   R                  XS9$ )	z
Insert a rectangle into the bin.

Parameters
-------------
size : (dimension,) float
  Size of rectangle to insert/

Returns
----------
inserted : (2,) float or None
  Position of insertion in the tree or None
  if the insertion was unsuccessful.
)sizerotateNr    r   T   r   r&   )r   insertr   r   copyrangelen_roll	_TOL_ZEROallanyargmaxr   vstackr   )r   r%   r&   r   attemptr   r"   roll	size_testfitsaxissplitss               r   r)   RectangleBin.insert=   s    ZZElll<G"	   == !!#)fQi'c$i(#eD&77	!YJ.3354 ,D )  
  IYJ&++--
 
 	!&&((M ! F+,"1IdOdj8qsDy %VBQZ0,vabz2JJ

1 zz!}##D#88r   )r   r   r   N)T)
__name__
__module____qualname____firstlineno____doc__r   propertyr"   r)   __static_attributes__ r   r   r   r      s&    
9" 
% 
%F9r   r   c                     SS/SS/// SQ/ SQ/ SQ//n X[        U 5      S-
     U      $ ! [         a"    [        R                  " X* S U SU*  /5      s $ f = f)a4  
A speedup for `numpy.roll` that only works
on flat arrays and is fast on 2D and 3D and
reverts to `numpy.roll` for other cases.

Parameters
-----------
a : (n,) any
  Array to roll
count : int
  Number of places to shift array

Returns
---------
rolled : (n,) any
  Input array shifted by requested amount

r   r    )r   r    r   )r   r   r    )r    r   r   r   N)r,   
IndexErrorr   concatenate)acountlookups      r   r-   r-      ss    ( 1v1vIy ABF8A
#E*++ 8~~qz1Wuf:6778s   + )AAc           	         [         R                  " U [         R                  S9n U R                  S   n[         R                  " [        U 5      SU45      n[         R                  " [        U 5      [        S9n[         R                  " U R                  SS95      SSS2   nU(       a4  Ub  UR                  U5      nO[         R                  R                  U5      nUc-  S/U-  U [         R                  " U SS9R                  5          /n	OS/U-  U/n	[        U	S9n
U GH  nX   nU
R                  XS	9nUGc}  UGcy  U
R                  n[         R                  " US
S9n[         R                   n[#        [        U5      5       H  n[         R$                  " U['        UU5      /5      n[         R(                  " UR                  S
S9[        U5      S45      n[         R*                  " UUR-                  S
S95        [         R.                  " USS9nUR1                  5       U:  a  UnUR3                  5       nUU   nU(       a  M    O   US
   WW   -   nUS
   R5                  5       nUU==   UU   -  ss'   [         R6                  " US   U45      R                  S
S9nUS   U   UU'   UUS   :  R9                  5       (       d   e[         R$                  " US
   U/5      n[         R$                  " UU/5      n[        US
   U/5      nSUl        [        U5      [        U5      /Ul        UR<                  S
   R                  [         R                  " US
S9US	9nUc   e[?        US
   S
   S5      (       d  Xg==   US
   S
   -  ss'   UR<                  S   R                  XS	9nUc   eUXk'   SX{'   Un
GM  Uc  GM  XU'   SX{'   GM     [@        RB                  (       a  [E        Xg   5      (       a   eXg   U4$ )a[  
Execute a single insertion order of smaller rectangles onto
a larger rectangle using a binary space partition tree.

Parameters
----------
extents : (n, dimension) float
  The size of the hyper-rectangles to pack.
size : None or (dim,) float
  Maximum size of container to pack onto.
  If not passed it will re-root the tree when items
  larger than any available node are inserted.
shuffle : bool
  Whether or not to shuffle the insert order of the
  smaller rectangles, as the final packing density depends
  on insertion order.
rotate : bool
  If True, allow integer-roll rotation.

Returns
---------
bounds : (m, 2, dim) float
  Axis aligned resulting bounds in space
transforms : (m, dim + 1, dim + 1) float
  Homogeneous transformation including rotation.
consume : (n,) bool
  Which of the original rectangles were packed,
  i.e. `consume.sum() == m`
r   r    r   r7   N        r!   r(   r   T)#r   
asanyarrayr   shapezerosr,   boolargsortmaxpermutationrandomptpr1   r   r)   r   infr+   r   r-   tilefill_diagonalsumprodminargminr*   r2   r/   r   r   r   r   strictbounds_overlap)r"   r%   shuffler&   rS   	dimensionoffsetconsumeorderroot_boundsrootindex	rectangleinsertedr   currentbestr4   stackchchoice_prodchoiceschoices_idxnew_maxnew_minnew_ori_max
bounds_ori
bounds_insnew_rootroot_offsetr   s                                  r   rectangles_singlerv      s   > mmG2::6Ga IXXs7|Q	23Fhhs7|40GJJw{{{*+DbD1E&&u-E II))%0E| uy('"&&q2I2P2P2R*ST uy($/ {+DN	;;y;8 [[FffV!,G 66Dc'l+'5D+A!BC WWUYYAY.Wq0AB  UYYAY%67 !ggbq1??$t+ G"-"4"4"6K&{3Dv# ,( Qi'+"66G Qinn&GK GK$88  ))VAY$89==1=EK'-ay'=K$6!9,113333 6!9k":;J 7G"45J $VAY$89H $H*:6Z8PQHN #..+22266&q3IRX2YK*** KN1-s33;q>!#44 NN1%,,Y,FE$$$!FM!GND!$5M!GNg j zz!&/2222?G##r   c                    SSK Jn  / n/ n[        U 5       He  u  pVUR                  R	                  SS5      nUR                  U/U-  5        UR                  UR                  UR                  S      /U-  5        Mg     [        SSU0UD6u  p/ n
[        [        R                  " U	5      S   U5       H<  u  p[XU      R                  5       nUR                  U5        U
R                  U5        M>     U" U
5      nXU	4$ )a  
Pack a list of Path2D objects into a rectangle.

Parameters
------------
paths: (n,) Path2D
  Geometry to be packed

Returns
------------
packed : trimesh.path.Path2D
  All paths packed into a single path object.
transforms : (m, 3, 3) float
  Homogeneous transforms to move paths from their
  original position to the new one.
consume : (n,) bool
  Which of the original paths were inserted,
  i.e. `consume.sum() == m`
r    )rD   quantityr   polygonsrA   )utilrD   	enumeratemetadatagetextendpolygons_closedrd   ry   zipr   nonzeror*   apply_transformappend)pathskwargsrD   packableoriginalre   pathrx   
transformsra   
positionedmatrixrh   packeds                 r   r   r   9  s    ( " HH '==$$Z3(*+--diil;<xGH ( #?H??JJRZZ03Z@(--/''" A $Fw&&r   c                    SSK JnJn  U" U 5      u  pE[        SSU0UD6u  pg[        R
                  " SUR                  5       [        U 5      5        [        XeU   S9n[        R                  " [        XG   U5       V	V
s/ s H  u  p[        R                  " X5      PM     sn
n	5      n[        R                  (       aw  [        U5      (       a   e[        R                  " [        [        R                   " U5      S   U5       VVs/ s H  u  pU" X   US9PM     snn5      n[        U5      (       a   eX4$ s  sn
n	f s  snnf )	a  
Pack polygons into a rectangle by taking each Polygon's OBB
and then packing that as a rectangle.

Parameters
------------
polygons : (n,) shapely.geometry.Polygon
  Source geometry
**kwargs : dict
  Passed through to `packing.rectangles`.

Returns
-------------
transforms : (m, 3, 3) float
  Homogeonous transforms from original frame to
  packed frame.
consume : (n,) bool
  Which of the original polygons was packed,
  i.e. `consume.sum() == m`
r    )polygon_boundspolygons_obbr"   z$%i/%i parts were packed successfullyr   r"   r   )r   rA   )ry   r   r   
rectanglesr   debugrX   r,   roll_transformr   r   r   dotr   r\   r]   r   )ry   r   r   r   obbr"   r   ra   r4   rE   br   re   mcheck_bounds                  r   ry   ry   g  s   , 7  )LC !;;F;OFII4gkkmS]S 1ABDCd4KL4KDA266!<4KLMJ
zz!&))))hh !$BJJw$7$:J G GHE xq9 G
 "+.... Ms   >"D7
D=
c           	         [         R                  " U [         R                  S9n U R                  S   nUb  XS-  -  n [         R                  " U SS9n	Sn
SnUc  SnO[         R
                  R                  US9n[        U5       H  n[        XUS:g  X\S	9u  pUR                  5       n[         R                  " UR                  S
U45      SS9nUb  [         R                  " UU-  5      U-  n X   R                  5       [         R                  " U5      -  nUU
:  d  UU:  d  M  Un
UnX/nUU:  d  M  UR                  5       (       d  M    O   Ub  WS==   U/U* ///-  ss'   [        R                  " U SU
S 35        W$ )af  
Run multiple iterations of rectangle packing, this is the
core function for all rectangular packing.

Parameters
------------
extents : (n, dimension) float
  Size of hyper-rectangle to be packed
size : None or (dimension,) float
  Size of sheet to pack onto. If not passed tree will be allowed
  to create new volume-minimizing parent nodes.
density_escape : float
  Exit early if rectangular density is above this threshold.
spacing : float
  Distance to allow between rectangles
iterations : int
  Number of iterations to run
rotate : bool
  Allow right angle rotations or not.
quanta : None or float
  Discrete "snap" interval.
seed
  If deterministic results are needed seed the RNG here.

Returns
---------
bounds :  (m, 2, dimension) float
  Axis aligned bounding boxes of inserted hyper-rectangle.
inserted : (n,) bool
  Which of the original rect were packed.
r   r    N       @rI   rK   r   )seed)r"   r%   r^   r&   rS   rJ   z  iterations packed with density z0.3f)r   r   r   rM   rY   rS   default_rngr+   rv   rX   rT   reshapeceilr/   r   r   )r"   r%   density_escapespacing
iterationsr&   quantar   dimareabest_density
best_countrS   ir   r)   rF   extents_alldensityresults                       r   r   r     s   T hhwbjj1G
--
CS=  777#DLJ|&&D&1: +a
 

ffV^^RI6Q?ggkF23f<G ,""$rww{';; \!UZ%7"LJ%F 'FJJLL5 8 q	yG8*-..	II<\$<OPQMr   power_resizededuplicater   r   r   modec           	         SSK Jn  U(       a  [        R                  " U  Vs/ s H  n[	        UR                  5       5      PM     snSSS9u  pn[        U
 Vs/ s H  oU   R                  PM     snSUUUS9u  pUR                  5       (       d   eX   n[        R                  " [        R                  " USS9U  Vs/ s H  oR                  PM     sn5      (       d   eO@[        U  Vs/ s H  oR                  PM     snSUUUS9u  pUR                  5       (       d   eUc  SnO[        U5      nUS	S	2S4   R                  5       R                  [        5      n[        R                  " UR                  S
5      SS9US-  -   nUR                  5       R                  [        5      nU(       aJ  S[        R                  " [        R                   " U5      5      -  R                  [        R"                  5      nUcX  [%        U  Vs1 s H  oR&                  iM     sn5      nU[        R(                  " U Vs/ s H  n[+        U5      PM     sn5         nUR-                  U[/        U5      5      n[1        5       n[3        X5       Ha  u  nn[/        U5      U;  a2  US   US   UR                  S   -
  US   -
  4nUR5                  UUS9  MG  UR7                  [/        U5      5        Mc     UU4$ s  snf s  snf s  snf s  snf s  snf s  snf )ak  
Pack a list of images and return result and offsets.

Parameters
------------
images : (n,) PIL.Image
  Images to be packed
power_resize : bool
  Should the result image be upsized to the nearest
  power of two? Not every GPU supports materials that
  aren't a power of two size.
deduplicate
  Should images that have identical hashes be inserted
  more than once?
mode
  If passed return an output image with the
  requested mode, otherwise will be picked
  from the input images.

Returns
-----------
packed : PIL.Image
  Multiple images packed into result
offsets : (n, 2) int
   Offsets for original image to pack
r   )ImageT)return_indexreturn_inverseF)r"   r&   r   r   r   r    rI   N)rJ   r   r   box)PILr   r   uniquehashtobytesr   r%   r/   r   rT   introundastyper   r   log2int64listr   r1   r,   newtuplesetr   pasteadd)imagesr   r   r   r   r   r   r   r   _re   inverser   r)   r`   r"   r%   modesr   r   doneimgoffcorners                           r   r   r     s   F II(./1T!))+/dSW
' $-23UAY^^U3!
 zz|||{{266&q1F3KFqFFF3KLLLL $%+,VVVV,!
 zz|||g, AqD\!((-FffV^^G,151EG==?!!#&DRWWRWWT]++33BHH=|f-ffff-. RYY61A678 YYtU4[)F5D'S:T!!fd1g3c!f<=FLL&L)HHU3Z  ( 6>y 0 4 4L -0 .  7s#   #K/K4>K9
+K>L8L
c                 &   U  Vs/ s H  o"R                   PM     nn[        R                  " U Vs/ s H  o"R                  R                  PM     sn5      n[        R                  " U Vs/ s H  oUR                  R
                  PM     sn5      n[        U40 UD6u  px[        R                  " [        Xh   [        XtU   S95       VV	s/ s H9  u  pY[        R                  " U	[        R                  R                  U5      5      PM;     sn	n[        R                  S9n
[        [        R                  " U5      S   U
5       VVs/ s H&  u  pX   R                  5       R                  U5      PM(     nnnXU4$ s  snf s  snf s  snf s  sn	nf s  snnf )a  
Pack 3D meshes into a rectangular volume using box packing.

Parameters
------------
meshes : (n,) trimesh.Trimesh
  Input geometry to pack
**kwargs : dict
  Passed to `packing.rectangles`

Returns
------------
placed : (m,) trimesh.Trimesh
  Meshes moved into the rectangular volume.
transforms : (m, 4, 4) float
  Homogeneous transform moving mesh from original
  position to being packed in a rectangular volume.
consume : (n,) bool
  Which of the original meshes were inserted,
  i.e. `consume.sum() == m`
r   r   r   )bounding_box_orientedr   r   	primitiver"   	transformr   r   r   r   linalginvr   r   r*   r   )meshesr   r   obbs
obb_extentoobb_transformr   ra   rr   re   Tplaceds                 r   r   r   d  sV   . .44V##VD4=1;;..=>JHHTBTkk33TBCM !6v6OF  &f6IJ	
 FF1biimmA&'	
 jj	J BJJw/2J??HE 	,,Q/?  
 w&&5 5=B	
s   E8E=*F	A F
-Fc                 F   SSK Jn  SSKJn  SSKJn  [        XS9nU  Vs/ s H  ob" US9PM
     nn[        XuU5       HU  u  pn
UR                  U	5        [        R                  " UR                  U
5      (       d   eU" 5       UR                  l        MW     U" U5      $ s  snf )z
Visualize a 3D box packing.

Parameters
------------
extents : (n, 3) float
  AABB size before packing.
bounds : (n, 2, 3) float
  AABB location after packing.

Returns
------------
scene : trimesh.Scene
  Scene with boxes at requested locations.
r   r   )Scene)random_colorr   r"   )creationr   scener   visualr   r   r   r   r   r   r   face_colors)r"   r   r   r   r   r   er   r   r   checks              r   	visualizer     s      %  v?J&-.gc!ngF.F;5	&!{{188U+++++~ < = /s   Br   r"   returnc           
      Z  ^^ [        U 5      [        U5      :w  a  [        S5      e[        U5      S:X  a  / $ [        R                  " U SS9nUR                  S   n[        R
                  " [        R                  " US-   5      [        U 5      SS45      n[        R                  " [        R                  " S5      [        R                  " / SQ/ SQ/ SQ/5      /5      [        R                  " [        R                  " S	5      / S
Q/ SQ/ SQ/ SQ// SQ/ SQ/ SQ/ SQ//5      /n[        UR                  S   5       H  n[        R                  " XSS9n[        R                  " X'-
  SS9[        :  nUR                  5       (       d  MM  XSS-
     U   n	[        R
                  " [        R                  " US-   5      UR                  5       SS45      n
U SS2S4   U   Xx   S-  -   U
SS2SU2U4'   U
 Vs/ s H  n[        R                  " X5      PM     snXH'   M     [        R                  (       au  US:X  a/  SSKJm  [%        U4S j['        XU5       5       5      (       d   e U$ US:X  a/  SSKJm  [%        U4S j['        XU5       5       5      (       d   e U$ [        S5      eU$ s  snf )a7  
Packing returns rotations with integer "roll" which
needs to be converted into a homogeneous rotation matrix.

Currently supports `dimension=2` and `dimension=3`.

Parameters
--------------
bounds : (n, 2, dimension) float
  Axis aligned bounding boxes of packed position
extents : (n, dimension) float
  Original pre-rolled extents will be used
  to determine rotation to move to `bounds`.

Returns
----------
transforms : (n, dimension + 1, dimension + 1) float
  Homogeneous transformation to move cuboid at the origin
  into the position determined by `bounds`.
z`bounds` must match `extents`r   r    rI   r'   )rK         rK   )      ?rK   rK   )rK   rK   r      )       r   r   r   )r   r   r   r   )rK   r   rK   rK   )rK   rK   rK   r   )r   r   r   r   )rK   rK   r   rK   r   Nr   r   c              3   |   >#    U  H1  u  pn[        T" US 9R                  U5      R                  U5      v   M3     g7f)r   Nr   r   r   ).0r   r   r   r   s       r   	<genexpr>!roll_transform.<locals>.<genexpr>
  s;      ;GA! Q77:AA1EE;s   9<)rf   c              3      >#    U  H:  u  pn[        T" U* S -  US -  /S9R                  U5      R                  U5      v   M<     g7f)r   r!   Nr   )r   r   r   r   rf   s       r   r   r     sK      ;GA! A261q5/:JJ1MTTVWXX;s   AAzunsupported dimension)r,   
ValueErrorr   rT   rM   rV   eyer   r+   r4   r.   r0   rX   r   r   r\   r   r   r/   r   rf   )r   r"   passedr_   r   rG   r4   rolledokmatr`   r   r   rf   s               @@r   r   r     sj   * 6{c'l"899
7|q	 VVF#FQI WWRVVIM*S[!Q,?@F 	VVAY"2O_!UVW	
 	q	,,((	 -(,(		
	F0 gmmA&' Q/ VVV_A.:vvxx ]#D)	A.1a0@A+1!Q$<+;fj3>N+Nq*9*i'(.45fbffQnf5
 (" zz>& "6F;     M !^+ "6F;     M 455M- 6s   3 J(c                    ^ [         R                  " U 5      [         R                  " X* /S5      -   n[        U5      m[	        U4S j[        U 5       5       5      $ )aW  
Check to see if multiple axis-aligned bounding boxes
contains overlaps using `rtree`.

Parameters
------------
bounds : (n, 2, dimension) float
  Axis aligned bounding boxes
epsilon : float
  Amount to shrink AABB to avoid spurious floating
  point hits.

Returns
--------------
overlap : bool
  True if any bound intersects any other bound.
)r    r   r    c              3      >#    U  H3  u  p[        TR                  UR                  5       5      5      U1:g  v   M5     g 7f)N)r   intersectionravel)r   r   rh   trees      r   r   !bounds_overlap.<locals>.<genexpr>2  s4      IZ:1Dgmmo./A36IZs   ;>)r   r   r   r   r0   r{   )r   epsilonpaddedr   s      @r   r]   r]     sR    & XXf

GX+>	 JJFvD IRSYIZ  r   )NFTN)NgGz?N2   TNN)FFr   NNN)g:0yE>)r>   numpyr   	constantsr   r   typedr   r   r   r	   r
   r   rz   r   r   r.   r   r-   rv   r   ry   r   rO   strr   r   r   r   r]   rA   r   r   <module>r     s      J J ( 	q9 q9h8:S$l+'\1l 
	_H $&" $dd d !	d
 7
d fd 3-dN1'h>b9 by bWW=M bJr   