
    ^j                        d Z ddlmZ ddl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Z	 d	 	 	 	 	 	 	 dd	Zy
)z
build123d Pack

name: pack.py
by:   fischman
date: November 9th 2023

desc:
    Utility code for packing objects in a squarish 2D area.
    )annotations)Callable
Collection)	dataclass)cast)LocationPos)Shapec                  
 t          G d d             
fd
fdfd}
fd
fdt        |       dkD  sJ t        t        |       D cg c]  \  }}| ||       ||      f c}}d	 d
      }t        |d d
      } 
d|d   d   |d   d         g }|D ]_   d   d         }|r |d   d         }n |d   d         }|j	                  d   |j
                  |j                  f       a t        |d       D 	cg c]  }	|	d   |	d   f c}	S c c}}w c c}	w )a_  Takes an iterable of objects to pack into a square(ish) 2D
    arrangement, and return a list of (x,y) locations to place each to
    achieve the packing.
    Based on https://codeincomplete.com/articles/bin-packing/ and
    implemented as a straight-forward port of
    https://github.com/jakesgordon/bin-packing/blob/master/js/packer.growing.js
    c                  p    e Zd ZU dZded<   dZded<   dZded<   dZded<   dZded	<   d
Z	ded<   d
Z
ded<   y
)_pack2d.<locals>._NodeFboolusedr   floatxywhNz'_Node' | Nonedownright)__name__
__module____qualname__r   __annotations__r   r   r   r   r   r        G/opt/ringagent/.cad-venv/lib/python3.12/site-packages/build123d/pack.py_Noder   #   sD    d5555#n# $~$r   r   c                    | j                   r* | j                  ||      xs  | j                  ||      S d   | j                  k  rd   | j                  k  r| S y N      )r   r   r   r   r   )startr   r   	find_nodeos      r   r$   z_pack2d.<locals>.find_node-   sT    ::U[[!Q/N9UZZA3NNQ4577?qtuwwLr   c                   | j                   rJ d| _          | j                  | j                  |z   | j                  | j                  |z
        | _         | j                  |z   | j                  | j                  |z
  |      | _        | S )NT)r   r   r   r   r   r   r   r   r   r   r   )noder   r   r   s      r   
split_nodez_pack2d.<locals>.split_node4   sk    99}	DFFdffqjDFFdffqjI	TVVaZ466TVVaZ1E
r   c                8   | j                   k  }|j                  k  }|xr j                  j                   | z   k\  }|xr j                   j                  |z   k\  }|r	 | |      S |r	 | |      S |r	 | |      S |r	 | |      S J d d|  d|        )NzFailed to grow! root: z, w: z, h: r   r   )	r   r   can_grow_downcan_grow_rightshould_grow_rightshould_grow_down	grow_down
grow_rightroots	         r   	grow_nodez_pack2d.<locals>.grow_node;   s    TVVdff*G466A:0F(Edff!.Da##Q?"a##Q?"E.tfE!E!EEur   c                     dddj                   | z   j                   j                   | j                               | |      }|sJ d        || |      S )NTr   )r   r   r   r'   z2Failed to grow right! root: {root}, w: {w}, h: {h}r+   r   r   r(   r   r$   r2   r)   s      r   r1   z_pack2d.<locals>.grow_rightK   sl    ffqjff$&&A0
 q!$IIIt$1%%r   c                     dddj                   j                  |z    j                  j                   |             | |      }|sJ d        || |      S )NTr   )r   r   r   r'   z1Failed to grow down! root: {root}, w: {w}, h: {h}r+   r5   s      r   r0   z_pack2d.<locals>.grow_downZ   sl    ffffqj466Q/
 q!$HHHt$1%%r   r   c                &    t        | d   | d         S r    )minds    r   <lambda>z_pack2d.<locals>.<lambda>l   s    c!A$!o r   T)keyreversec                &    t        | d   | d         S r    )maxr9   s    r   r;   z_pack2d.<locals>.<lambda>o   s    #adAaD/ r   Fr!   r"   r+   c                    | d   S )Nr   r   )ts    r   r;   z_pack2d.<locals>.<lambda>y   s
    QqT r   )r<   )r   lensorted	enumerateappendr   r   )objectswidth_fn	length_fnr3   ir%   sorted_objectstranslationsr(   rA   r   r$   r0   r1   r2   r)   s        `    @@@@@@r   _pack2drL      s^    % % %F && w<!6?6HIFQ!Xa[)A,	'I%N
 N0ISWXN.+A..2CA2FGDL 4qtQqT*dAaD!A$/DQqT1Q4(DQqT466466234 #)>"JKQQqT1Q4LKK 	J Ls    D7
#D=c                   | D ci c]"  }||j                         j                  ||fz   $ c}t        | fdfd      }t        | |      D cg c]  \  }}t	        |d   |j                         j
                  j                  z
  |d   |j                         j
                  j                  z
  df      t        dd|r%|j                         j
                  j                   ndf      z  |z   }}}d }|D cg c]  }|j                          }}t        |      D ]5  \  }	}
t        ||	dz   d       D ]  \  }} ||
|      sJ d|	 d	| d
        7 |S c c}w c c}}w c c}w )a5  Pack objects in a squarish area in Plane.XY.

    Args:
        objects (Collection[Shape]): objects to arrange
        padding (float): space between objects
        align_z (bool, optional): align shape bottoms to Plane.XY. Defaults to False.

    Returns:
        Collection[Shape]: rearranged objects
    c                >    t        t        |          j                  S N)r   r
   Xr%   bounding_boxess    r   r;   zpack.<locals>.<lambda>   s    >$ua.9;; r   c                >    t        t        |          j                  S rO   )r   r
   YrQ   s    r   r;   zpack.<locals>.<lambda>   s    N4q>:<< r   )rG   rH   r   r!   c                   t        | j                  j                  |j                  j                        }t        | j                  j                  |j                  j                        }t        | j                   j                  |j                   j                        }t        | j                   j                  |j                   j                        }||kD  xr ||kD  S rO   )r?   r8   rP   rT   )bb1bb2min_xmin_ymax_xmax_ys         r   _overlappingzpack.<locals>._overlapping   s    CGGIIswwyy)CGGIIswwyy)CGGIIswwyy)CGGIIswwyy)u}..r   NzObjects at indexes z and z	 overlap!)bounding_boxsizerL   zipr   r8   rP   rT   r	   ZrD   )rF   paddingalign_zr%   rK   rA   
translatedr\   bbrI   bb_ijbb_jrR   s                @r   packrh   |   s    NUUa)..'71CCCUN;<L '<0	 Q 	!A$)--///18H8L8L8N8N1NPQRS
q!ann&**,,,Q?
@	A
	J / %/	/q!..
	/B	/R= :4 AEG- 	:GAt#d :$QCuQCy9: 	::
 9 V  
0s   'EB!E!>E'N)rF   zCollection[object]rG   Callable[[object], float]rH   ri   returnzCollection[tuple[float, float]])F)rF   Collection[Shape]ra   r   rb   r   rj   rk   )__doc__
__future__r   collections.abcr   r   dataclassesr   typingr   build123d.geometryr   r	   build123d.topology.shape_corer
   rL   rh   r   r   r   <module>rs      s~   	 # 0 !  , /cLcL'cL )cL %	cLN AF**).*9=**r   