Ë
    :vžj·  ã                   óT  — d dl Zd dlmZ d dlmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ dd	lm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  	 d dl!Z"	 d dl'm(Z( d„ Z)dee   dee   fd„Z*dee   ez  fd„Z+deez  fd„Z,d„ Z-d,d„Z.d-d„Z/d,dede0fd„Z1d„ Z2d.dededz  fd„Z3ded ee   fd!„Z4d/d"efd#„Z5d$„ Z6d,d%„Z7d0d"efd&„Z8d1d'„Z9	 	 	 	 	 	 	 d2d(e:d)e0fd*„Z;d3defd+„Z<y# e#$ rZ$ddl%m&Z&  e&e$«      Z"Y dZ$[$Œ¤dZ$[$ww xY w# e#$ rZ$ddl%m&Z&  e&e$«      Z(Y dZ$[$Œ½dZ$[$ww xY w)4é    N)Úops)ÚPolygoné   )ÚboundsÚgeometryÚgraphÚgrouping)Úlog)Útol_path)Úreduce_cascade)Útransform_points)Ú	ArrayLikeÚIterableÚNDArrayÚNumberÚSeedÚfloat64Úint64)Úrandom_generatoré   )Úfit_circle_check)Úresample_path)ÚExceptionWrapper)ÚIndexc           
      óö  — t        j                  «       }t        | «      dk(  r't        j                  g t        j
                  ¬«      |fS t        | «      dk(  re| d   €'t        j                  g t        j
                  ¬«      |fS |j                  d«       t        j                  dgt        j
                  ¬«      |fS t        | «      D ��ci c]  \  }}|t        |dg «      “Œ c}}j                  «       D ��ci c]  \  }}t        |«      dk(  r||“Œ }}}|j                   |j                  «       «       t        |«      dkD  rAt        t         |j                  «        |j                  «       dgt        |«      z  «      «      } |j                  «       D ]u  \  }}j                  |«      D ]\  }	||	k(  rŒ	| |   j!                  | |	   «      r|j#                  ||	«       Œ3| |	   j!                  | |   «      sŒK|j#                  |	|«       Œ^ Œw t%        |j'                  «       «      }
t        j                  t)        |
j                  «       «      «      }t        j                  t)        |
j                  «       «      «      }||dz  dk(     }t        |«      dkD  rÎ|j+                  «       dkD  r»g }|t        j,                  |D �cg c]  }|
|   ‘Œ	 c}«         }|D ]R  }|||
|   dz   k(     }|j/                  |j1                  t        j2                  ||«      «      j5                  «       «       ŒT t        j6                  |t        j                  «       «      }|j                  |«       ||fS c c}}w c c}}w c c}w )az  
    Given a list of shapely polygons with only exteriors,
    find which curves represent the exterior shell or root curve
    and which represent holes which penetrate the exterior.

    This is done with an R-tree for rough overlap detection,
    and then exact polygon queries for a final result.

    Parameters
    -----------
    polygons : (n,) shapely.geometry.Polygon
       Polygons which only have exteriors and may overlap

    Returns
    -----------
    roots : (m,) int
        Index of polygons which are root
    contains : networkx.DiGraph
       Edges indicate a polygon is
       contained by another polygon
    r   ©Údtyper   Nr   é   r   )ÚnxÚDiGraphÚlenÚnpÚarrayr   Úadd_nodeÚ	enumerateÚgetattrÚitemsÚadd_nodes_fromÚkeysr   ÚzipÚvaluesÚintersectionÚcontainsÚadd_edgeÚdictÚ	in_degreeÚlistÚmaxÚargsortÚextendÚsubgraphÚappendÚedgesÚfrom_edgelist)Úpolygonsr-   ÚiÚpolygonÚkÚvr   ÚtreeÚbÚjÚdegreeÚindexesÚdegreesÚrootsr7   ÚrÚrootÚchildrens                     úf/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/trimesh/path/polygons.pyÚenclosure_treerI       s  € ô0 �z‰z‹|€Hä
ˆ8ƒ}˜ÒÜ�x‰x˜¤"§(¡(Ô+¨XÐ5Ð5Ü	ˆX‹˜!Ò	ð �A‰;ÐÜ—8‘8˜B¤b§h¡hÔ/°Ð9Ð9à×Ñ˜!ÔÜ�x‰x˜˜¤2§8¡8Ô,¨hÐ6Ð6ô AJÈ(Ô@Sô
Ù@S±*°!°WˆAŒw�w ¨"Ó-Ñ-Ð@Sò
ç
‰%‹'ðôñ‰DˆAˆqô ˆq‹6�QŠ;ð	 	
ˆ1‰ðð ñ ð ×Ñ˜K˜FŸK™K›MÔ*ä
ˆ6ƒ{�Q‚ô
 ”S˜˜Ÿ™›¨¨¯©«¸$¸Ä#ÀfÃ+Ñ9MÓNÓOˆð �—‘–‰ˆˆ1à×"Ñ" 1Ö%ˆAà�AŠvØð ˜‰{×#Ñ# H¨Q¡KÔ0Ø×!Ñ! ! QÕ'Ø˜!‘×%Ñ% h¨q¡kÕ2Ø×!Ñ! ! QÕ'ñ &ð ô �(×$Ñ$Ó&Ó'€Fä�h‰h”t˜FŸK™K›MÓ*Ó+€GÜ�h‰h”t˜FŸM™M›OÓ,Ó-€Gà�W˜q‘[ QÑ&Ñ'€Eô ˆ7ƒ|�aÒ˜GŸK™K›M¨AÒ-àˆà”b—j‘j±UÓ!;±U° &¨£)°UÑ!;Ó<Ñ=ˆãˆDØ˜w¨&°©,¸Ñ*:Ñ:Ñ;ˆHØ�L‰L˜×*Ñ*¬2¯9©9°X¸tÓ+DÓE×KÑKÓMÕNð ô ×#Ñ# E¬2¯:©:«<Ó8ˆà×Ñ Ô&à�(ˆ?Ðùóm
ùóùò\ "<s   ÃM*Ã8M0ËM6
r7   Úverticesc                 ó4  — t        |t        j                  «      sJ ‚g }t        j                  | d¬«      D ]S  }	 t        t        ||   «      «      }t        |d«      r|j                  |j                  «       n|j                  |«       ŒU t        |«      dk(  r|S t        |«      \  }}|D ��cg c]H  }t        ||   j                  ||   j                  «       D �cg c]  }||   j                  ‘Œ c}¬«      ‘ŒJ c}}S # t        $ r Y ŒÕw xY wc c}w c c}}w )aw  
    Given an edge list of indices and associated vertices
    representing lines, generate a list of polygons.

    Parameters
    -----------
    edges : (n, 2)
      Indexes of vertices which represent lines
    vertices : (m, 2)
      Vertices in 2D space.

    Returns
    ----------
    polygons : (p,) shapely.geometry.Polygon
      Polygon objects with interiors
    Údfs)ÚmodeÚgeomsr   ©ÚshellÚholes)Ú
isinstancer"   Úndarrayr   Ú
traversalsÚrepair_invalidr   Úhasattrr4   rN   r6   Ú
ValueErrorr!   rI   Úexteriorr)   )	r7   rJ   r9   rL   ÚrepairedrD   r>   rF   r:   s	            rH   Úedges_to_polygonsrZ   ‚   s  € ô$ �h¤§
¡
Ô+Ð+Ð+ð €Hä×Ñ ¨E×2ˆð		ä%¤g¨h°s©mÓ&<Ó=ˆHä�x Ô)Ø—‘ §¡Õ/à—‘ Ô)øð 3ô ˆ8ƒ}˜ÒØˆô ! Ó*�K€Eˆ4ñ ôñ
 ˆDô	 	Ø˜4‘.×)Ñ)Ø15°d±·±Ô1BÓCÑ1B¨A�8˜A‘;×'Ó'Ð1BÑCö	
ð òð øô ò 	Ùð	üò Dùós*   ºAD Â/-DÃDÃ2
DÄ 	DÄDÄDr9   c                 óà   — dgt        | «      z  }dgt        | «      z  }t        | «      D ]  \  }}t        |«      \  ||<   ||<   Œ t        j                  |«      t        j                  |«      fS )z?
    Find the OBBs for a list of shapely.geometry.Polygons
    N)r!   r%   Úpolygon_obbr"   r#   )r9   Ú
rectanglesÚ
transformsr:   Úps        rH   Úpolygons_obbr`   ¶   sj   € ð �œ#˜h›-Ñ'€JØ�œ#˜h›-Ñ'€JÜ˜(Ö#‰ˆˆ1Ü'2°1£~Ñ$ˆ
�1‰�z !’}ð $ä�8‰8�JÓ¤§¡¨*Ó!5Ð5Ð5ó    r;   c                 óÞ  — t        | d«      r*t        j                  | j                  j                  «      }n(t        | t        j                  «      r| }nt        d«      ‚t        j                  |«      \  }}t        j                  rdt        ||¬«      }t        j                  | dz  |j                  d¬«      «      sJ ‚t        j                  |dz  |j                  d¬«      «      sJ ‚||fS )a÷  
    Find the oriented bounding box of a Shapely polygon.

    The OBB is always aligned with an edge of the convex hull of the polygon.

    Parameters
    -------------
    polygons : shapely.geometry.Polygon
      Input geometry

    Returns
    -------------
    transform : (3, 3) float
      Transformation matrix
      which will move input polygon from its original position
      to the first quadrant where the AABB is the OBB
    extents : (2,) float
      Extents of transformed polygon
    rX   z"polygon or points must be provided©ÚpointsÚmatrixç       @r   ©Úaxis)rV   r"   Ú
asanyarrayrX   ÚcoordsrR   rS   rW   r   Úoriented_bounds_2DÚtolÚstrictr   ÚallcloseÚminr2   )r;   rd   Ú	transformÚextentsÚmoveds        rH   r\   r\   Á   sÂ   € ô( ˆw˜
Ô#Ü—‘˜w×/Ñ/×6Ñ6Ó7‰Ü	�GœRŸZ™ZÔ	(Ø‰äÐ=Ó>Ð>ä×2Ñ2°6Ó:Ñ€Iˆwä
‡z‚zÜ ¨°yÔAˆÜ�{‰{˜G˜8 c™>¨5¯9©9¸!¨9Ó+<Ô=Ð=Ð=Ü�{‰{˜7 S™=¨%¯)©)¸¨)Ó*;Ô<Ð<Ð<à�gÐÐra   c                 óö  — t        j                  |t         j                  ¬«      }t        | d«      r*t	        | |«      D ��cg c]  \  }}t        ||«      ‘Œ }}}|S t        t        j                  | j                  j                  «      |«      dd…dd…f   }| j                  D �cg c]4  }t        t        j                  |j                  «      |«      dd…dd…f   ‘Œ6 }}t        ||¬«      }|S c c}}w c c}w )aV  
    Transform a polygon by a a 2D homogeneous transform.

    Parameters
    -------------
    polygon : shapely.geometry.Polygon
      2D polygon to be transformed.
    matrix  : (3, 3) float
      2D homogeneous transformation.

    Returns
    --------------
    result : shapely.geometry.Polygon
      Polygon transformed by matrix.
    r   rN   Nr   rO   )r"   ri   r   rV   r*   Útransform_polygonr   r#   rX   rj   Ú	interiorsr   )r;   re   r_   ÚtÚresultrP   r:   rQ   s           rH   rt   rt   æ   så   € ô  �]‰]˜6¬¯©Ô4€Fäˆw˜Ô Ü69¸'À6Ô6JÔKÑ6J©d¨a°Ô# A qÕ)Ð6JˆÑKØˆäœRŸX™X g×&6Ñ&6×&=Ñ&=Ó>ÀÓGÊÈ2ÈAÈ2ÈÑN€Eð FM×EVÒEVóÙEVÀÔœŸ™ !§(¡(Ó+¨VÓ4²Q¸¸¸°UÓ;ÐEVð 
ð ô ˜5¨Ô.€FØ€Mùó Lùò
s   ÁC0Â&9C6c                 óx  — |�F|j                   dk(  sJ ‚t        t        j                  | j                  j
                  «      |¬«      }n)t        j                  | j                  j
                  «      }t        j                  |j                  d¬«      |j                  d¬«      g«      }|j                   dk(  sJ ‚|S )aƒ  
    Get the transformed axis aligned bounding box of a
    shapely Polygon object.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Polygon pre-transform
    matrix : (3, 3) float or None.
      Homogeneous transform moving polygon in space

    Returns
    ------------
    bounds : (2, 2) float
      Axis aligned bounding box of transformed polygon.
    )é   ry   rc   r   rg   ©r   r   )Úshaper   r"   r#   rX   rj   ro   r2   )r;   re   rd   r   s       rH   Úpolygon_boundsr|     s˜   € ð" ÐØ�|‰|˜vÒ%Ð%Ð%Ü!¬¯©°'×2BÑ2B×2IÑ2IÓ)JÐSYÔZ‰ä—‘˜'×*Ñ*×1Ñ1Ó2ˆä�X‰X�v—z‘z q�zÓ)¨6¯:©:¸1¨:Ó+=Ð>Ó?€FØ�<‰<˜6Ò!Ð!Ð!Ø€Mra   c                 óp  ‡‡— ddl m} ˆˆfd„}‰€|j                  «       Š‰j                  dd«       | j                  j
                  dk(  r!| j                  D �cg c]
  } ||«      ‘Œ c} n-t        | d«      r| D �cg c]
  } ||«      ‘Œ c} n
| � || «       |r|j                  «        ‰S c c}w c c}w )zó
    Plot a shapely polygon using matplotlib.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Polygon to be plotted
    show : bool
      If True will display immediately
    **kwargs
      Passed to plt.plot
    r   Nc                 ó¬   •—  ‰j                   | j                  j                  i ‰¤Ž | j                  D ]  } ‰j                   |j                  i ‰¤Ž Œ  y ©N)ÚplotrX   Úxyru   )ÚsingleÚinteriorÚaxesÚkwargss     €€rH   Úplot_singlezplot.<locals>.plot_single1  sG   ø€ Øˆ�	‰	�6—?‘?×%Ñ%Ð0¨Ò0Ø×(Ô(ˆHØˆD�I‰I�x—{‘{Ð- fÓ-ñ )ra   ÚequalÚdatalimÚMultiPolygonÚ__iter__)	Úmatplotlib.pyplotÚpyplotr„   Ú
set_aspectÚ	__class__Ú__name__rN   rV   Úshow)r;   r�   r„   r…   Úpltr†   r:   s     ``   rH   r€   r€   "  s¢   ù€ õ $õ.ð €|Ø�x‰x‹zˆØ‡O�O�G˜YÔ'à×Ñ×!Ñ! ^Ò3Ø!(§¢Ó/¡˜A‰�Q� Ó/Ü	�˜*Ô	%Ù!(Ó)¡˜A‰�Q� Ó)Ø	Ð	Ù�GÔáØ�‰Œ
à€Kùò 	0ùâ)s   ÁB.Á=B3Ú
resolutionc                 ó¢   ‡‡— ˆˆfd„}‰€ddgŠ || j                   «      g dœ}| j                  D ]  }|d   j                   ||«      «       Œ |S )aã  
    Return a version of a polygon with boundaries re-sampled
    to a specified resolution.

    Parameters
    -------------
    polygon : shapely.geometry.Polygon
      Source geometry
    resolution : float
      Desired distance between points on boundary
    clip : (2,) int
      Upper and lower bounds to clip
      number of samples to avoid exploding count

    Returns
    ------------
    kwargs : dict
     Keyword args for a Polygon constructor `Polygon(**kwargs)`
    c                 óŽ   •— | j                   ‰z  }t        t        j                  |g‰¢­Ž «      }t	        | j
                  |¬«      S )N)Úcount)ÚlengthÚintr"   Úclipr   rj   )Úboundaryr•   r˜   r’   s     €€rH   Úresample_boundaryz.resample_boundaries.<locals>.resample_boundary]  s<   ø€ ð —‘ *Ñ,ˆÜ”B—G‘G˜EÐ) DÒ)Ó*ˆÜ˜XŸ_™_°EÔ:Ð:ra   é   éÈ   rO   rQ   )rX   ru   r6   )r;   r’   r˜   rš   r…   rƒ   s    ``   rH   Úresample_boundariesr�   H  s\   ù€ õ*;ð €|Ø�3ˆxˆá(¨×)9Ñ)9Ó:ÀRÑH€FØ×%Ô%ˆØˆw‰×ÑÑ0°Ó:Õ;ð &ð €Mra   c                 óŽ   — t        | d   «      dk(  r| d   S t        j                  | d   t        j                  | d   «      f«      S )zþ
    Stack the boundaries of a polygon into a single
    (n, 2) list of vertices.

    Parameters
    ------------
    boundaries : dict
      With keys 'shell', 'holes'

    Returns
    ------------
    stacked : (n, 2) float
      Stacked vertices
    rQ   r   rP   )r!   r"   Úvstack)Ú
boundariess    rH   Ústack_boundariesr¡   n  sH   € ô ˆ:�gÑÓ 1Ò$Ø˜'Ñ"Ð"Ü�9‰9�j Ñ)¬2¯9©9°ZÀÑ5HÓ+IÐJÓKÐKra   c                 ó’  — t        | j                  «      dk(  rôt        j                  t        j                  | j
                  d«      d¬«      j                  «       }t        | j                  j                  |¬«      }|�Žt        j                  |d   dz  dt        j                  «      }t        j                  |d   d|gz   |d   d|gz
  gt        j                  ¬	«      }t        j                  dd
ggt        j                  ¬	«      }||fS ddlm} ddlm}	 |€Ft        j                  t        j                  | j
                  d«      d¬«      j                  «       dz  }t'        | ||¬«      }
t)        |
«      }
 ||
«      } |	j*                  | g|j,                  j.                  ¢­Ž }t        j0                  |d«      }t        j2                  |j4                  t        j                  ¬	«      }|||   j7                  d
¬«         }t        j8                  |«      }t        j:                  t        |j,                  «      t        j                  ¬	«      }t        j<                  t        |«      «      ||<   |j,                  |   }||   }t>        j@                  r-t        j                  ||   |j,                  |   z
  «      dk  sJ ‚||fS )ai  
    Given a shapely polygon, find the approximate medial axis
    using a voronoi diagram of evenly spaced points on the
    boundary of the polygon.

    Parameters
    ----------
    polygon : shapely.geometry.Polygon
      The source geometry
    resolution : float
      Distance between each sample on the polygon boundary
    clip : None, or (2,) int
      Clip sample count to min of clip[0] and max of clip[1]

    Returns
    ----------
    edges : (n, 2) int
      Vertex indices representing line segments
      on the polygon's medial axis
    vertices : (m, 2) float
      Vertex positions in space
    r   rz   rg   )ÚscaleÚradiusiô  çñhãˆµøä>Úcenterr   r   )ÚVoronoi©Ú
vectorizedéd   )r;   r’   r˜   F)!r!   ru   r"   ÚptpÚreshaper   r2   r   rX   rj   r˜   Úinfr#   r   r   Úscipy.spatialr§   Úshapelyr©   r�   r¡   r-   rJ   ÚTr6   ri   Úridge_verticesÚallÚuniqueÚzerosÚarangerl   rm   )r;   r’   r˜   r£   ÚfitÚepsilonrJ   r7   r§   r©   ÚsamplesÚvoronoir-   ÚridgeÚ	containedÚmaskÚedges_finals                    rH   Úmedial_axisr¾   ‚  s=  € ô0 ˆ7×ÑÓ Ò"ä—‘”r—z‘z '§.¡.°&Ó9ÀÔB×FÑFÓHˆä˜w×/Ñ/×6Ñ6¸eÔDˆàˆ?ä—g‘g˜c (™m¨cÑ1°4¼¿¹Ó@ˆGÜ—x‘xØ�X‘ ! W Ñ-¨s°8©}ÀÀ7¸|Ñ/KÐLÜ—j‘jôˆHô
 —H‘H˜q !˜f˜X¬R¯X©XÔ6ˆEØ˜(�?Ð"å%Ý"àÐÜ—V‘VœBŸJ™J w§~¡~°vÓ>ÀQÔG×KÑKÓMÐPSÑSˆ
ô "¨'¸jÈtÔT€Gä˜wÓ'€Gá�gÓ€Gà"ˆz×"Ñ" 7Ð@¨W×-=Ñ-=×-?Ñ-?Ò@€Hä�y‰y˜ 5Ó)€Hä�M‰M˜'×0Ñ0¼¿¹ÔA€Eà�(˜5‘/×%Ñ%¨1Ð%Ó-Ñ.€Eô —	‘	˜%Ó €IÜ�8‰8”C˜×(Ñ(Ó)´·±Ô:€DÜ—i‘i¤ I£Ó/€Dˆ�Oð ×Ñ 	Ñ*€Hà�u‘+€Kä
‡z‚zä�v‰v�h˜{Ñ+¨g×.>Ñ.>¸uÑ.EÑEÓFÈÒMÐMÐMà˜Ð Ð ra   Úreturnc                 óh  — t        | j                  «      | j                  j                  | j                  j                  | j                  | j                  | j
                  j                  g}t        | d¬«      \  }}}}|j                  |«       t        j                  |t        j                  ¬«      S )a  
    Return a vector containing values representative of
    a particular polygon.

    Parameters
    ---------
    polygon : shapely.geometry.Polygon
      Input geometry

    Returns
    ---------
    identifier : (8,) float
      Values which should be unique for this polygon.
    T)Úreturn_centeredr   )r!   ru   Úconvex_hullÚarear–   rX   Úsecond_momentsr4   r"   r#   r   )r;   rw   Ú_Ú	principals       rH   Ú
identifierrÇ   Ñ  sŒ   € ô  	ˆG×ÑÓØ×Ñ× Ñ Ø×Ñ×"Ñ"Ø�‰Ø�‰Ø×Ñ×Ñð€Fô (¨ÀÔFÑ€A€y�!�QØ
‡M�M�)Ôä�8‰8�F¤"§*¡*Ô-Ð-ra   Úseedc                 ó>  — t        |«      }t        j                  t        j                  |j	                  | «      t        j
                  z  dz  «      t        j
                  dz  z  «      }|j	                  | «      |z  }t        j                  t        j                  |«      t        j                  |«      f«      |j                  d«      z  }t        j                  ||d   f«      }t        |«      j                  d«      }t        |d«      r|j                  d   S |S )aã  
    Generate a random polygon with a maximum number of sides and approximate radius.

    Parameters
    ---------
    segments : int
      The maximum number of sides the random polygon will have
    radius : float
      The approximate radius of the polygon desired
    seed : None or int
      Seed for deterministic results, otherwise OS entropy.

    Returns
    ---------
    polygon : shapely.geometry.Polygon
      Geometry object with random exterior and no interiors.
    r   )éÿÿÿÿr   r   ç        rN   )r   r"   ÚsortÚcumsumÚrandomÚpiÚcolumn_stackÚcosÚsinr¬   rŸ   r   ÚbufferrV   rN   )Úsegmentsr¤   rÈ   rÎ   ÚanglesÚradiird   r;   s           rH   Úrandom_polygonr×   ð  sÖ   € ô$ ˜dÓ#€FÜ�W‰W”R—Y‘Y˜vŸ}™}¨XÓ6¼¿¹Ñ>ÀÑBÓCÄrÇuÁuÈqÁyÑQÓR€FØ�M‰M˜(Ó# fÑ,€Eä�_‰_œbŸf™f V›n¬b¯f©f°V«nÐ=Ó>ÀÇÁÈwÓAWÑW€FÜ�Y‰Y˜  q¡	Ð*Ó+€FÜ�f‹o×$Ñ$ SÓ)€GÜˆw˜Ô Ø�}‰}˜QÑÐØ€Nra   c                 óœ   — t        j                  t        j                  | j                  d«      d¬«      }|dz  j	                  «       dz  }|S )zò
    For a Polygon object return the diagonal length of the AABB.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Source geometry

    Returns
    ------------
    scale : float
      Length of AABB diagonal
    rz   r   rg   r   ç      à?)r"   r«   r¬   r   Úsum)r;   rq   r£   s      rH   Úpolygon_scalerÛ     s?   € ô �f‰f”R—Z‘Z §¡°Ó7¸aÔ@€GØ�a‰Z×ÑÓ #Ñ%€Eà€Lra   c                 óL  — dgt        | «      z  }t        | «      D ]A  \  }}t        |«      dk  rŒ	 t        |«      }|j                  r|||<   nt	        ||«      ||<   ŒC t        j                  |«      }|S # t
        $ r Y Œft        $ r t        j                  dd¬«       Y Œ‡w xY w)aV  
    Given a sequence of connected points turn them into
    valid shapely Polygon objects.

    Parameters
    -----------
    paths : (n,) sequence
      Of (m, 2) float closed paths
    scale : float
      Approximate scale of drawing for precision

    Returns
    -----------
    polys : (p,) list
      Filled with Polygon or None

    Nr   zunrecoverable polygonT)Úexc_info)r!   r%   r   Úis_validrU   rW   ÚBaseExceptionr
   Úerrorr"   r#   )Úpathsr£   r9   r:   Úpathr;   s         rH   Úpaths_to_polygonsrã   "  s¨   € ð$ ˆvœ˜E›
Ñ"€HÜ˜UÖ#‰ˆˆ4Üˆt‹9�qŠ=ð ð
	>Ü˜d“mˆGØ×ÒØ%�˜’ä,¨W°eÓ<�˜‘øð $ô" �x‰x˜Ó!€Hà€Oøô ò 	áÜò 	>Ü�I‰IÐ-¸×=ð	>ús   ±,A6Á6	B#ÂB#Â"B#c                 ó€  — ddl m} t        j                  | j                  d«      }t        j
                  |d¬«      }t        ||z  «      }t        |«      }	|d   ||	j                  |df«      z  z   }
 |j                  | g|
j                  ¢­Ž }|
|   g}t        |d   «      }||k\  r|d   d| S t        |«      D ]g  }|	j                  |df«      |z  |d   z   }
 |j                  | g|
j                  ¢­Ž }|j                  |
|   «       |t        |d   «      z  }||kD  sŒg n t        j                  |«      d| }|S )aö  
    Use rejection sampling to generate random points inside a
    polygon. Note that this function may return fewer or no
    points, in particular if the polygon as very little area
    compared to the area of the axis-aligned bounding box.

    Parameters
    -----------
    polygon : shapely.geometry.Polygon
      Polygon that will contain points
    count : int
      Number of points to return
    factor : float
      How many points to test per loop
    max_iter : int
      Maximum number of intersection checks is:
      > count * factor * max_iter
    seed : None or int
      Seed for deterministic results, otherwise OS entropy.

    Returns
    -----------
    hit : (n, 2) float
      Random points inside polygon
      where n <= count
    r   r¨   rz   rg   r   NrÊ   )r¯   r©   r"   r¬   r   r«   r—   r   rÎ   r-   r°   r!   Úranger6   rŸ   )r;   r•   ÚfactorÚmax_iterrÈ   r©   r   rq   Úper_looprÎ   rd   r¼   ÚhitÚ	hit_countrÅ   s                  rH   Úsamplerë   K  sG  € õ8 #ô �Z‰Z˜Ÿ™¨Ó/€FÜ�f‰f�V !Ô$€Gô �5˜6‘>Ó"€Hô ˜dÓ#€FØ�A‰Y˜ 6§=¡=°(¸A°Ó#?Ñ?Ñ?€Fàˆ:×Ñ˜wÐ2¨¯©Ò2€DØ�$‰<ˆ.€CÜ�C˜‘F“€Ià�EÒØ�1‰v�f�uˆ~Ðô �8Ž_ˆà—-‘- ¨1 Ó.°Ñ8¸FÀ1¹IÑEˆà"ˆz×"Ñ" 7Ð6¨V¯X©XÒ6ˆØ�
‰
�6˜$‘<Ô à”S˜˜R™“\Ñ!ˆ	à�uÓÙð ô �)‰)�C‹.˜˜%Ð
 €Cà€Jra   c                 ó¢  — t        | d«      r| j                  r| S | j                  t        j                  «      }t        |d«      rD|j
                  t        j                  |j
                  D �cg c]  }|j                  ‘Œ c}«         }|j                  r.t        j                  |j                  | j                  |¬«      r|S |€Gdt        j                  t        j                  | j                  d«      d¬«      j                  «       z  }nd|z  }t        | j                   «      dk(  �rA| j"                  j                  |«      j                   }t        |«      dk(  rXt%        |d   ¬	«      j                  |«      }|j                  r.t        j                  |j                  | j                  |¬«      r|S t        j&                  | j"                  j(                  «      }t        j*                  d
t        j,                  |d¬«      dz  j/                  d¬«      dz  dkD  «      }	t%        ||	   ¬	«      }
|
j                  r.t        j                  |
j                  | j                  |¬«      r|
S | j                  |«      j                  | «      }t        |d«      rTt        j&                  |j
                  D �cg c]  }|j                  ‘Œ c}«      }|j
                  |j                  «          S |j                  rCt        j                  |j                  | j                  |¬«      rt1        j2                  d«       |S t5        d«      ‚c c}w c c}w )aþ  
    Given a shapely.geometry.Polygon, attempt to return a
    valid version of the polygon through buffering tricks.

    Parameters
    -----------
    polygon : shapely.geometry.Polygon
      Source geometry
    rtol : float
      How close does a perimeter have to be
    scale : float or None
      For numerical precision reference

    Returns
    ----------
    repaired : shapely.geometry.Polygon
      Repaired polygon

    Raises
    ----------
    ValueError
      If polygon can't be repaired
    rÞ   rN   )Úrtolgü©ñÒMb`?rz   r   rg   r   )rP   Tr   rÙ   g:Œ0âŽyE>z2Recovered invalid polygon through double bufferingzunable to recover polygon!)rV   rÞ   rÓ   rl   ÚzerorN   r"   ÚargmaxrÃ   Úiscloser–   r«   r¬   r   Úmeanr!   ru   rX   r   r#   rj   r6   ÚdiffrÚ   r
   ÚdebugrW   )r;   r£   rí   Úbasicr:   ÚdistanceÚringsÚreconrd   r³   ÚdedupeÚbufferedr?   Úareass                 rH   rU   rU   ’  sx  € ô0 ˆw˜
Ô#¨×(8Ò(8Øˆð �N‰Nœ3Ÿ8™8Ó$€Eäˆu�gÔØ—‘œBŸI™I°u·{²{Ó&C±{°! q§v£v°{Ñ&CÓDÑEˆð ‡~‚~œ"Ÿ*™* U§\¡\°7·>±>ÈÕMØˆà€}Øœ2Ÿ6™6¤"§*¡*¨W¯^©^¸VÓ"DÈ1ÔM×RÑRÓTÑT‰à˜5‘=ˆô ˆ7×ÑÓ Ó"ð × Ñ ×'Ñ'¨Ó1×;Ñ;ˆÜˆu‹:˜Š?ä %¨¡(Ô+×2Ñ2°8Ó<ˆEà�~Š~¤"§*¡*¨U¯\©\¸7¿>¹>ÐPTÕ"UØ�ô —‘˜'×*Ñ*×1Ñ1Ó2ˆô —‘˜4¤"§'¡'¨&°qÔ"9¸QÑ">×!CÑ!CÈÐ!CÓ!KÈsÑ!RÐUYÑ!YÓZˆä˜v f™~Ô.ˆà�?Š?œrŸz™z¨&¯-©-¸¿¹ÈdÕSØˆMð �~‰~˜hÓ'×.Ñ.°¨yÓ9€Häˆx˜Ô!Ü—‘¨(¯.ª.Ó9©. Q˜!Ÿ&›&¨.Ñ9Ó:ˆØ�~‰~˜eŸl™l›nÑ-Ð-ð ×ÒœRŸZ™Z¨¯©¸¿¹ÈdÕSÜ�	‰	ÐFÔGØˆä
Ð1Ó
2Ð2ùòa 'DùòP :s   Á.M
Ê6MÚpreciseÚprecise_epsc	                 ó4  — t        j                  |t         j                  ¬«      }|t         j                  j	                  |«      z  }t        j
                  || j                  j                  «      }	|rz|	|kD  }
|	| k  }t        j                  |
j                  «       |j                  «       g«      }|j                  «       dk(  r|j                  «       }n|j                  «       }|
|g|   }n|	|kD  }|| j                     j                  d¬«      }| j                  |   }t        j                  ||¬«      }t!        | j"                  |«      dd…dd…f   }|�r| j$                  |   }t'        t        j(                  t        j*                  |«      «      dz   «      }t        j,                  ||«      }|t        j.                  ||dd…dd…f   f«         }|dd…g d¢f   |dd…g d	¢f   k(  j                  d¬«      j1                  d¬«       }t3        j4                  ||   D �cg c]  }t7        |«      ‘Œ c}«      j9                  |«      j9                  | «      S t;        j<                  |t        j>                  |«      d   ¬
«      }| j@                  jC                  d«      }g }|D ]L  }||   jC                  d«      }tE        jF                  |d¬«      }|jI                  tK        ||   |¬«      «       ŒN d}|�|tM        |«      z  }|�7t        jN                  |d¬«      jQ                  «       }|tM        |«      |z  z  }n"tS        |«      dk(  r|d   S tS        |«      dk(  rytU        d„ |«      } | �!| j9                  |«      j9                  | «      S yc c}w )a   
    Project a mesh onto a plane and then extract the polygon
    that outlines the mesh projection on that plane.

    Note that this will ignore back-faces, which is only
    relevant if the source mesh isn't watertight.

    Also padding: this generates a result by unioning the
    polygons of multiple connected regions, which requires
    the polygons be padded by a distance so that a polygon
    union produces a single coherent result. This distance
    is calculated as: `apad + (rpad * scale)`

    Parameters
    ----------
    mesh : trimesh.Trimesh
      Source geometry
    normal : (3,) float
      Normal to extract flat pattern along
    origin : None or (3,) float
      Origin of plane to project mesh onto
    ignore_sign : bool
      Allow a projection from the normal vector in
      either direction: this provides a substantial speedup
      on watertight meshes where the direction is irrelevant
      but if you have a triangle soup and want to discard
      backfaces you should set this to False.
    rpad : float
      Proportion to pad polygons by before unioning
      and then de-padding result by to avoid zero-width gaps.
    apad : float
      Absolute padding to pad polygons by before unioning
      and then de-padding result by to avoid zero-width gaps.
    tol_dot : float
      Tolerance for discarding on-edge triangles.
    precise : bool
      Use the precise projection computation using shapely.
    precise_eps : float
      Tolerance for precise triangle checks.

    Returns
    ----------
    projected : shapely.geometry.Polygon or None
      Outline of source mesh

    Raises
    ---------
    ValueError
      If max_regions is exceeded
    r   r   r   rg   )ÚoriginÚnormalNr   )r   r   r   )r   r   r   )Únodes)rÊ   é   )rÊ   r   )Úrequire_count)r7   rJ   rË   c                 ó$   — | j                  |«      S r   )Úunion)Úar?   s     rH   Ú<lambda>zprojected.<locals>.<lambda>ƒ  s   € ¨!¯'©'°!¬*ra   )+r"   r#   r   ÚlinalgÚnormÚdotÚface_normalsr°   rÚ   ro   rï   ÚargminÚface_adjacencyr²   r   Úplane_transformr   rJ   Úfacesr—   ÚabsÚlog10ÚroundrÐ   Úanyr   Úunary_unionr   rÓ   r   Úconnected_componentsÚnonzeroÚedges_sortedr¬   r	   Ú
group_rowsr4   rZ   Úfloatr«   r2   r!   r   )!Úmeshrÿ   rþ   Úignore_signÚrpadÚapadÚtol_dotrû   rü   Údot_faceÚfrontÚbackr•   ÚpickÚsideÚadjacency_checkÚ	adjacencyÚto_2DÚvertices_2Dr  ÚdigitsÚroundedÚ	trianglesÚvalidÚfÚface_groupsr7   r9   ÚedgeÚgroupÚpaddingr£   Úreduceds!                                    rH   Ú	projectedr1  å  sW  € ô| �X‰X�f¤B§J¡JÔ/€FØ
Œb�i‰i�n‰n˜VÓ$Ñ$€Fô �v‰v�f˜d×/Ñ/×1Ñ1Ó2€HÙð ˜7Ñ"ˆØ˜7˜(Ñ"ˆô —‘˜%Ÿ)™)›+ t§x¡x£zÐ2Ó3ˆØ�9‰9‹;˜!Òà—<‘<“>‰Dð —<‘<“>ˆDà�tˆ}˜TÑ"‰ð ˜'Ñ!ˆð ˜4×.Ñ.Ñ/×3Ñ3¸Ð3Ó;€OØ×#Ñ# OÑ4€Iô ×$Ñ$¨F¸6ÔB€Eä" 4§=¡=°%Ó8º¸B¸Q¸B¸Ñ?€Kâð —
‘
˜4Ñ ˆô ”R—V‘VœBŸH™H [Ó1Ó2°QÑ6Ó7ˆÜ—(‘(˜;¨Ó/ˆàœBŸO™O¨U°Eº!¸R¸a¸R¸%±LÐ,AÓBÑCˆ	ð šAšy˜LÑ)¨Y²qº)°|Ñ-DÑD×IÑIÈqÐIÓQ×UÑUØð Vó 
ð 
ˆô �O‰O°¸5Ò1AÓBÑ1A¨AœW Q�ZÐ1AÑBÓCß‰V�KÓ ß‰V�[�LÓ!ð	
ô ×,Ñ,¨Y¼b¿j¹jÈÓ>NÈqÑ>QÔR€Kð ×Ñ×%Ñ% gÓ.€Eà€HÛˆà�U‰|×#Ñ# GÓ,ˆä×#Ñ# D¸Ô:ˆà�‰Ô)°°U±ÀkÔRÕSð ð €GØÐà”5˜“;ÑˆØÐä—‘�{¨Ô+×/Ñ/Ó1ˆà”5˜“; Ñ&Ñ&‰ô 
ˆX‹˜!Ò	Ø˜‰{ÐÜ	ˆX‹˜!Ò	Øô Ñ4°hÓ?€Gð ÐØ�~‰~˜gÓ&×-Ñ-¨w¨hÓ7Ð7ð ùòQ Cs   È$Nc                 óŠ  — t        j                  d«      }|r=t        j                  | j                  j                  «       |dd…df<   t        | |«      } t        j                  | j                  j                  «      }t        j                  |d   |dd f«      j                  \  }}|j                  \  }}||z  ||z  z
  }t        j                  |||z  ||z  z   ||z  z   z  «      dz  }	t        j                  |||z  ||z  z   ||z  z   z  «      dz  }
t        j                  |||z  d|z  |z  z   d|z  |z  z   ||z  z   z  «      dz  }| j                  D ]ø  }t        j                  |j                  «      }t        j                  |d   |dd f«      j                  \  }}|j                  \  }}||z  ||z  z
  }|	t        j                  |||z  ||z  z   ||z  z   z  «      dz  z  }	|
t        j                  |||z  ||z  z   ||z  z   z  «      dz  z  }
|t        j                  |||z  d|z  |z  z   d|z  |z  z   ||z  z   z  «      dz  z  }Œú |	|
|g}|s|S t        j                  |
|	z
  dz  dz  |dz  z   «      }|	|
z   dz  |z   }|	|
z   dz  |z
  }||g}t        j                  |dd	¬
«      rd}nKt        j                  |	|
«      rdt         j                  z  }n!dt        j                  d|z  |	|
z
  z  «      z  }t        j                  |«      }t        j                   |«      }||d<   ||d<   | |d<   ||d<   ||||fS )a>  
    Calculate the second moments of area of a polygon
    from the boundary.

    Parameters
    ------------
    polygon : shapely.geometry.Polygon
      Closed polygon.
    return_centered : bool
      Get second moments for a frame with origin at the centroid
      and perform a principal axis transformation.

    Returns
    ----------
    moments : (3,) float
      The values of `[Ixx, Iyy, Ixy]`
    principal_moments : (2,) float
      Principal second moments of inertia: `[Imax, Imin]`
      Only returned if `centered`.
    alpha : float
      Angle by which the polygon needs to be rotated, so the
      principal axis align with the X and Y axis.
      Only returned if `centered`.
    transform : (3, 3) float
      Transformation matrix which rotates the polygon by alpha.
      Only returned if `centered`.
    ry   Nr   rÊ   g      (@g      8@rf   rË   gê-�™—q=)Úatolr   g      Ð?rÙ   )r   r   )r   r   )r   r   )r   r   )r"   Úeyer#   Úcentroidrj   rt   rX   rŸ   r°   rÚ   ru   Úsqrtrð   rÏ   ÚarctanrÑ   rÒ   )r;   rÁ   rp   rj   Úx1Úy1Úx2Úy2r=   ÚIxxÚIyyÚIxyrƒ   ÚmomentsrF   ÚImaxÚIminÚprincipal_momentsÚalphaÚ	cos_alphaÚ	sin_alphas                        rH   rÄ   rÄ   Š  si  € ô: —‘�q“	€IÙäŸH™H W×%5Ñ%5×%<Ñ%<Ó=Ð=ˆ	�"�1�"�a�%ÑÜ# G¨YÓ7ˆô �X‰X�g×&Ñ&×-Ñ-Ó.€Fä�Y‰Y˜˜r™
 F¨3¨B KÐ0Ó1×3Ñ3�F€BˆØ�X‰X�F€Bˆà
ˆR‰�"�r‘'Ñ€AÜ
�&‰&��b˜2‘g  R¡Ñ'¨"¨r©'Ñ1Ñ2Ó
3°dÑ
:€CÜ
�&‰&��b˜2‘g  R¡Ñ'¨"¨r©'Ñ1Ñ2Ó
3°dÑ
:€CÜ
�&‰&��b˜2‘g  B¡¨¡Ñ+¨a°"©f°r©kÑ9¸BÀ¹GÑCÑDÓ
EÈÑ
L€Cà×%Ô%ˆÜ—‘˜(Ÿ/™/Ó*ˆä—‘˜F 2™J¨¨s°¨Ð4Ó5×7Ñ7‰ˆˆBØ—‘‰ˆˆBà�‰G�b˜2‘gÑˆØŒr�v‰v�a˜2 ™7 R¨"¡WÑ,¨r°B©wÑ6Ñ7Ó8¸4Ñ?Ñ?ˆØŒr�v‰v�a˜2 ™7 R¨"¡WÑ,¨r°B©wÑ6Ñ7Ó8¸4Ñ?Ñ?ˆØŒr�v‰v�a˜2 ™7 Q¨¡V¨b¡[Ñ0°1°r±6¸B±;Ñ>ÀÀbÁÑHÑIÓJÈTÑQÑQ‰ð &ð �C˜ˆo€GáØˆô �7‰7�S˜3‘Y #Ñ%¨!Ñ+¨c°1©fÑ4Ó5€DØ�#‰I˜Ñ˜tÑ#€DØ�#‰I˜Ñ˜tÑ#€DØ˜t˜Ðô 
‡z�z�#�s Õ'Ø‰Ü	�‰�C˜Ô	à”r—u‘u‘‰à”b—i‘i  c¡	¨S°3©YÑ 7Ó8Ñ8ˆô —‘�u“€IÜ—‘�u“€Ià€Iˆd�OØ€Iˆd�OØ �j€Iˆd�OØ€Iˆd�OàÐ% u¨iÐ7Ð7ra   r   )NTN)NN)r›   g      ð?N)g      ø?é
   N)NrÙ   )NTr¥   Nç»½×Ùß|Û=FrG  )F)=Únumpyr"   r¯   r   Úshapely.geometryr   Ú r   r   r   r	   Ú	constantsr
   r   rl   Ú	iterationr   Útransformationsr   Útypedr   r   r   r   r   r   r   Úutilr   Úsimplifyr   Ú	traversalr   Únetworkxr   rß   ÚEÚ
exceptionsr   Úrtree.indexr   rI   rZ   r`   r\   rt   r|   r€   r  r�   r¡   r¾   rÇ   r×   rÛ   rã   rë   rU   Úboolr1  rÄ   © ra   rH   Ú<module>rX     s›  ðÛ Ý Ý $ç 0Ó 0Ý Ý 'Ý &Ý .ß N× NÑ NÝ #Ý &Ý $ðÛð Ý!ò_ðD1˜W U™^ð 1°w¸wÑ7Gó 1ðh6˜8 GÑ,¨yÑ8ó 6ð"˜ 7Ñ*ó "òJó@ó8#ñL# ð #°eó #òLLñ(L!˜ð L!¨f°t©mó L!ð^.˜ð . G¨GÑ$4ó .ñ>°ó ò<ó(&ñRD¸$ó DóNP3ðl ØØ	Ø	ØØØñb8ð ðb8ð ób8ñJV8˜Gô V8øðs ò õ .á	˜!Ó	…Bûðûð ò  å-á˜QÓ…Eûð	 ús0   ÁC* ÁD
 Ã*DÃ/DÄDÄ
D'ÄD"Ä"D'