Ë
    :vžjƒ?  ã                   ó$  — d dl Z d dlZd dlZddlmZmZmZ ddlm	Z	m
Z
mZmZ ddlmZ 	 d dlZd„ Zdd	„Zd
„ Zdd„Z G d„ d«      Z	 	 	 	 dde	de
dz  dedz  dededeej4                     fd„Zd„ Zy# e$ rZddlmZ  ee«      ZY dZ[Œ\dZ[ww xY w)é    Né   )Ú	constantsÚgroupingÚutil)Ú	ArrayLikeÚIntegerÚNDArrayÚNumberé   )Úis_ccw)ÚExceptionWrapperc                 óø   — t        j                  «       }g }t        | «      D ]@  \  }}|j                  r|j	                  |«       Œ$|j                  |j                  |¬«       ŒB |t        j                  |«      fS )a‡  
    Given a set of entity objects generate a networkx.Graph
    that represents their vertex nodes.

    Parameters
    --------------
    entities : list
       Objects with 'closed' and 'nodes' attributes

    Returns
    -------------
    graph : networkx.Graph
        Graph where node indexes represent vertices
    closed : (n,) int
        Indexes of entities which are 'closed'
    )Úentity_index)	ÚnxÚGraphÚ	enumerateÚclosedÚappendÚadd_edges_fromÚnodesÚnpÚarray)ÚentitiesÚgraphr   ÚindexÚentitys        úg/workspace/moltex-experiments/.pixi/envs/default/lib/python3.12/site-packages/trimesh/path/traversal.pyÚvertex_graphr      si   € ô" �H‰H‹J€EØ€FÜ" 8Ö,‰ˆˆvØ�=Š=Ø�M‰M˜%Õ ð × Ñ  §¡¸EÐ ÕBð -ð ”"—(‘(˜6Ó"Ð"Ð"ó    c                 óÎ  ‡ ‡‡‡‡— ˆˆˆˆˆ fd„}|�|j                   d   dk7  rd}n-t        |t        j                  ‰ ‰ d   «         «      }|dz  dz
  }t        j                  ‰ t        j
                  ¬«      Š g Št        j                  t        ‰ «      dz   «      D ]_  }t        j                  t        j                  d«      |z   t        ‰ «      «      }‰ |   }	 |j                  |	Ž d   }
‰j                  |
«       Œa t        j                  ‰«      dd|…   Št        ‰«      dk(  r|dk  r‰d   }‰|   j                  «        ‰S t        j                  ‰‰d   «      }t        j                  |«      }|D ]X  \  ŠŠ |‰‰   j                  ‰‰   j                  «      \  }}|€Œ/‰‰   j                  |¬«       ‰‰   j                  |¬«       ŒZ t        j                   ‰«      Š‰S )	aÉ  
    Convert a path of vertex indices to a path of entity indices.

    Parameters
    ----------
    vertex_path : (n,) int
        Ordered list of vertex indices representing a path
    graph : nx.Graph
        Vertex connectivity
    entities : (m,) list
        Entity objects
    vertices :  (p, dimension) float
        Vertex points in space

    Returns
    ----------
    entity_path : (q,) int
        Entity indices which make up vertex_path
    c                 ó  •— | d   |d   k(  ry| d   |d   k(  ry| d   |d   k(  ry| d   |d   k(  ryt         j                  j                  dj                  g d¢«      ‰‰‰‰   j                  ‰‰   j                  «       y	)
a“  
        Given two edges, figure out if the first needs to be
         reversed to keep the progression forward.

         [1,0] [1,2] -1  1
         [1,0] [2,1] -1 -1
         [0,1] [1,2]  1  1
         [0,1] [2,1]  1 -1

        Parameters
        ------------
        a : (2,) int
        b : (2,) int

        Returns
        ------------
        a_direction : int
        b_direction : int
        r   ©éÿÿÿÿr   r   )r#   r#   )r   r   )r   r#   Ú
)zedges not connected!zvertex path %szentity path: %szentity[a]: %s,zentity[b]: %s)NN)r   ÚlogÚdebugÚjoinÚpoints)ÚaÚbÚeaÚebr   Úentity_pathÚvertex_paths     €€€€€r   Úedge_directionz-vertex_to_entity_path.<locals>.edge_directionE   s—   ø€ ð( ˆQ‰4�1�Q‘4Š<ØØˆq‰T�Q�q‘TŠ\ØØˆq‰T�Q�q‘TŠ\ØØˆq‰T�Q�q‘TŠ\Øä�M‰M×ÑØ—	‘	òóð ØØ˜‘×#Ñ#Ø˜‘×#Ñ#ôð  r   Nr   r   r   ©Údtyper   )Ú	direction)Úshaper   r   r   Ú
asanyarrayÚint64ÚarangeÚlenÚmodÚget_edge_datar   Úunique_orderedÚreverseÚ	itertoolsÚpairwiseÚ
end_pointsr   )r.   r   r   Úverticesr/   Úccw_directionÚ	ccw_checkÚiÚvertex_path_posÚvertex_indexr   r   Ú
round_tripÚdaÚdbr+   r,   r-   s   ` `            @@@r   Úvertex_to_entity_pathrH   0   sÌ  ü€ ÷*-ð -ð^ Ð˜8Ÿ>™>¨!Ñ,°Ò1Ø‰ä˜8¤B§I¡I¨k¸;Àq¹>Ó$JÑKÓLˆ	Ø" Q™¨!Ñ+ˆô —-‘- ´2·8±8Ô<€Kà€Kä�Y‰Y”s˜;Ó'¨!Ñ+Ö,ˆäŸ&™&¤§¡¨1£°Ñ!1´3°{Ó3CÓDˆØ" ?Ñ3ˆØ*�u×*Ñ*¨LÐ9¸.ÑIˆØ×Ñ˜<Õ(ð -ô ×)Ñ)¨+Ó6±¸°ÑG€Kä
ˆ;Ó˜1Òà˜1ÒØ ‘NˆEØ�U‰O×#Ñ#Ô%àÐô —‘˜;¨°A©Ó7€JÜ×#Ñ# JÓ/€JÛ‰ˆˆBÙ ¨¡× 7Ñ 7¸À"¹×9PÑ9PÓQ‰ˆˆBØ‰>Ø�R‰L× Ñ ¨2Ð Ô.Ø�R‰L× Ñ ¨2Ð Õ.ð	 ô —(‘(˜;Ó'€KàÐr   c           	      ó  — t        | «      \  }}t        j                  |d«      j                  «       }t        j
                  j                  |«      }|D ].  }t        |«      dk  rŒ|j                  t        ||| |«      «       Œ0 |S )a,  
    Paths are lists of entity indices.
    We first generate vertex paths using graph cycle algorithms,
    and then convert them to entity paths.

    This will also change the ordering of entity.points in place
    so a path may be traversed without having to reverse the entity.

    Parameters
    -------------
    entities : (n,) entity objects
        Entity objects
    vertices : (m, dimension) float
        Vertex points in space

    Returns
    -------------
    entity_paths : sequence of (n,) int
        Ordered traversals of entities
    r"   r   )
r   r   ÚreshapeÚtolistr   ÚcyclesÚcycle_basisr7   r   rH   )r   r?   r   r   Úentity_pathsÚvertex_pathsr.   s          r   Úclosed_pathsrP   ž   s~   € ô, ! Ó*�M€Eˆ6ä—:‘:˜f gÓ.×5Ñ5Ó7€Lä—9‘9×(Ñ(¨Ó/€Ló $ˆäˆ{Ó˜aÒØà×ÑÔ1°+¸uÀhÐPXÓYÕZð $ð Ðr   c                 ó  — t        j                  |«      }t        |«      }|dk(  rt        d«      ‚|dk(  r-t        j                  | |d      j	                  ||¬«      «      }nng }t        |«      D ]I  \  }}| |   j	                  ||¬«      }||dz
  k\  r|j                  |«       Œ6|j                  |dd «       ŒK t        j                  |«      }|j                  d   dk(  r&t        |«      st        j                  |ddd…   «      }|S )a4  
    Turn a list of entity indices into a path of connected points.

    Parameters
    -----------
    entities : (j,) entity objects
       Objects like 'Line', 'Arc', etc.
    vertices: (n, dimension) float
        Vertex points in space.
    path : (m,) int
        Indexes of entities
    scale : float
        Overall scale of drawing used for
        Number tolerances in certain cases

    Returns
    -----------
    discrete : (p, dimension) float
       Connected points in space that lie on the
       path and can be connected with line segments.
    r   zCannot discretize empty path!r   )ÚscaleNr#   r   )r   r4   r7   Ú
ValueErrorÚdiscreter   r   Úvstackr3   r   Úascontiguousarray)	r   r?   ÚpathrR   Úpath_lenrT   rB   Ú	entity_idÚcurrents	            r   Údiscretize_pathr[   Å   s   € ô. �}‰}˜XÓ&€HÜ�4‹y€HØ�1‚}ÜÐ8Ó9Ð9Ø�1‚}ä—=‘= ¨$¨q©'Ñ!2×!;Ñ!;¸HÈEÐ!;Ó!RÓS‰ð ˆÜ% džO‰LˆAˆyà˜yÑ)×2Ñ2°8À5Ð2ÓIˆGà�X ‘\Ò"à—‘ Õ(ð —‘ ¨¨ Õ-ð ,ô —9‘9˜XÓ&ˆà‡~�~�aÑ˜AÒ¤f¨XÔ&6ä×'Ñ'¨±°2°©Ó7ˆà€Or   c                   ót   — e Zd Zdefd„Z	 d
dededeej                     fd„Z	de
deej                     fd„Zy	)Ú
PathSampler(   c                 óD  — t        j                  |«      | _        t        j                  | j                  d¬«      | _        t        j                  | j                  «      | _        | j                  t        j                  j                  kD  }| j                  j                  «       | _        | j                  |xx   | j                  |   j                  d«      z  cc<   | j                  j                  «       | _        t        j                   | j                  «      | _        y )Nr   ©Úaxisr"   )r   r   Ú_pointsÚdiffÚ_vectorsr   Úrow_normÚ_normsr   Útol_pathÚzeroÚcopyÚ	_unit_vecrJ   ÚsumÚlengthÚcumsumÚ	_cum_norm)Úselfr(   Únonzeros      r   Ú__init__zPathSample.__init__ü   sº   € ä—x‘x Ó'ˆŒäŸ™ §¡°1Ô5ˆŒä—m‘m D§M¡MÓ2ˆŒà—+‘+¤	× 2Ñ 2× 7Ñ 7Ñ7ˆØŸ™×+Ñ+Ó-ˆŒØ�‰�wÓ 4§;¡;¨wÑ#7×#?Ñ#?ÀÓ#HÑHÓà—k‘k—o‘oÓ'ˆŒô Ÿ™ 4§;¡;Ó/ˆ�r   Ú	distancesÚinclude_originalÚreturnc                 óŒ  — t        j                  | j                  |«      }t        j                  |dt	        | j
                  «      dz
  «      }t        j                  d| j                  «      |   }||z
  }| j
                  |   }| j                  |   }|||j                  d«      z  z   }|r—t        j                  t        j                  | j                  d«      |«       }	|	j                  «       rRt        j                  |t        j                  |	«      d   «      }
t        j                  ||
| j                  |	   d¬«      }|S )a\  
        Return points at the distances along the path requested.

        Parameters
        ----------
        distances
          Distances along the path to sample at.
        include_original
          Include the original vertices even if they are not
          specified in `distance`. Useful as this will return
          a result with identical area and length, however
          indexes of `distance` will not correspond with result.

        Returns
        --------
        samples : (n, dimension)
          Samples requested.
          `n==len(distances)` if not `include_original`
        r   r   r"   g        r_   )r   Úsearchsortedrm   Úclipr7   ri   r   ra   rJ   ÚisinÚanyro   Úinsert)rn   rq   rr   Ú	positionsÚoffsetsÚ
projectionr2   ÚoriginÚ	resampledÚ
uninsertedr   s              r   ÚsamplezPathSample.sample  s  € ô0 —O‘O D§N¡N°IÓ>ˆ	Ü—G‘G˜I q¬#¨d¯n©nÓ*=ÀÑ*AÓBˆ	Ü—)‘)˜A˜tŸ~™~Ó.¨yÑ9ˆà Ñ(ˆ
à—N‘N 9Ñ-ˆ	à—‘˜iÑ(ˆð ˜i¨*×*<Ñ*<¸WÓ*EÑEÑFˆ	áô Ÿ'™'¤"§)¡)¨D¯N©N¸CÓ"@À*ÓMÐMˆJà�~‰~ÔäŸ™¨	´2·:±:¸jÓ3IÈ!Ñ3LÓM�äŸI™I i°¸¿¹ÀZÑ8PÐWXÔY�	àÐr   Údistancec                 ó´  — t        j                  | j                  |«      }|| j                  |dz
     z
  }|t        j                  j
                  k  r| j                  d|dz    }nšt        j                  t        j                  | j                  t        j                  d«      |z      d¬«      j                  d«      «      }||z  }| j                  |   |z   }t        j                  | j                  d|dz    |f«      }t        j                  t        j                  |d¬«      «      j                  «       |z
  t        j                  j
                  k  sJ ‚|S )a=  
        Return a truncated version of the path.
        Only one vertex (at the endpoint) will be added.

        Parameters
        ----------
        distance
          Distance along the path to truncate at.

        Returns
        ----------
        path
          Path clipped to `distance` requested.
        r   Nr   r   r_   r#   )r   ru   rm   r   rf   Úmergera   r   Úunitizerb   r6   rJ   rU   rd   rj   )rn   r�   ÚpositionÚoffsetÚ	truncatedÚvectorÚendpoints          r   ÚtruncatezPathSample.truncate?  s   € ô —?‘? 4§>¡>°8Ó<ˆØ˜DŸN™N¨8°a©<Ñ8Ñ8ˆà”I×&Ñ&×,Ñ,Ò,ØŸ™ ^ x°!¡|Ð4‰Iä—\‘\Ü—‘˜Ÿ™¤R§Y¡Y¨q£\°HÑ%<Ñ=ÀAÔF×NÑNÈrÓRóˆFð �fÑˆFØ—|‘| HÑ-°Ñ6ˆHÜŸ	™	 4§<¡<°°(¸Q±,Ð#?ÀÐ"JÓKˆIä�M‰Mœ"Ÿ'™' )°!Ô4Ó5×9Ñ9Ó;¸hÑFÜ×Ñ×$Ñ$ò%ð 	%ð %ð Ðr   N)F)Ú__name__Ú
__module__Ú__qualname__r   rp   Úboolr	   r   Úfloat64r€   r
   rŠ   © r   r   r]   r]   û   sW   „ ð0˜yó 0ð$ >Cñ0Ø"ð0Ø6:ð0à	�—‘Ñ	ó0ðd ð ¨G°B·J±JÑ,?ô r   r]   r(   ÚcountÚstepÚ
step_roundrr   rs   c                 óä  — t        j                  | t         j                  ¬«      } |�|�t        d«      ‚|€|€t        d«      ‚t	        | «      }|�C|rA||j
                  k\  r| ddg   S t        t        j                  |j
                  |z  «      «      }|�"t        j                  d|j
                  |«      }n#|�!t        j                  d|j
                  |«      }|j                  |¬«      }t        j                  j                  rht        j                  | ddg   |ddg   z
  «      }|d   t        j                   j"                  k  sJ ‚|�"|d   t        j                   j"                  k  sJ ‚|S )aÑ  
    Given a path along (n,d) points, resample them such that the
    distance traversed along the path is constant in between each
    of the resampled points. Note that this can produce clipping at
    corners, as the original vertices are NOT guaranteed to be in the
    new, resampled path.

    ONLY ONE of count or step can be specified
    Result can be uniformly distributed (np.linspace) by specifying count
    Result can have a specific distance (np.arange) by specifying step


    Parameters
    ----------
    points:   (n, d) float
      Points in space
    count : int,
      Number of points to sample evenly (aka np.linspace)
    step : float
      Distance each step should take along the path (aka np.arange)
    step_round
      Alter `step` to the nearest integer division of overall length.
    include_original
      Include the exact original points in the output.

    Returns
    ----------
    resampled : (j,d) float
        Points on the path
    r0   z#Only step OR count can be specifiedz&Either step or count must be specifiedr   r#   )rr   r   )r   r   r�   rS   r]   rk   ÚintÚceilÚlinspacer6   r€   r   ÚtolÚstrictr   rd   rf   rƒ   )	r(   r‘   r’   r“   rr   ÚsamplerÚsamplesr~   Úchecks	            r   Úresample_pathr�   a  sQ  € ôJ �X‰X�f¤B§J¡JÔ/€FàÐ Ð 0ÜÐ>Ó?Ð?Øˆ˜D˜LÜÐAÓBÐBä˜Ó €GØÐ™JØ�7—>‘>Ò!Ø˜1˜b˜'‘?Ð"ä”B—G‘G˜GŸN™N¨TÑ1Ó2Ó3ˆàÐÜ—+‘+˜a §¡°Ó7‰Ø	Ð	Ü—)‘)˜A˜wŸ~™~¨tÓ4ˆà—‘˜wÐ9I�ÓJ€Iä‡}�}×ÒÜ—‘˜f a¨ W™o°	¸1¸b¸'Ñ0BÑBÓCˆØ�Q‰xœ)×,Ñ,×2Ñ2Ò2Ð2Ð2ØÐØ˜‘8œi×0Ñ0×6Ñ6Ò6Ð6Ð6àÐr   c                 ó"  — t        | «      }g }| j                  }| j                  }| j                  }| j                  }t        | j                  «      D �]“  \  }}t        ||   j                  «       «      }	|	j                  |«       g }
g }|	D ]Q  }||   }|
j                  t        j                  t        |«      «      t        |«      z   «       |j                  |«       ŒS t        j                  | j                   «      }||d<   t        j"                  t        |
«      dz
  g«      }| j$                  5  |j                   |t        j                  | j&                  |   «      t        j                  | j(                  «      |¬«      «       |d   j$                  j+                  |
||	   |	D �cg c]  }||   ‘Œ	 c}|dœ«       |d   j$                  j-                  «        ddd«       �Œ– t        j"                  |«      S c c}w # 1 sw Y   �Œ»xY w)a,  
    Split a Path2D into multiple Path2D objects where each
    one has exactly one root curve.

    Parameters
    --------------
    path : trimesh.path.Path2D
      Input geometry

    Returns
    -------------
    split : list of trimesh.path.Path2D
      Original geometry as separate paths
    Úsplit_2Dr   )r   r?   Úmetadatar#   )ÚpathsÚpolygons_closedrT   ÚrootN)Útyper¡   rT   r¢   Úenclosure_directedr   r£   ÚlistÚkeysr   r   r6   r7   Úextendrh   Údeepcopyr    r   Ú_cacher   r?   ÚupdateÚid_set)rW   ÚPath2DÚsplitr¡   rT   r¢   r¥   Ú
root_indexr£   Ú	connectedÚ	new_pathsÚnew_entitiesr   r   r    Únew_rootÚcs                    r   r®   r®   ¤  sÎ  € ô  �$‹Z€Fð €Eð �J‰J€EØ�}‰}€HØ×*Ñ*€OØ×0Ñ0Ðä% d§i¡i×0Ñˆ
�DäÐ+¨DÑ1×6Ñ6Ó8Ó9ˆ	à×Ñ˜Ôð ˆ	ØˆãˆEØ˜%‘LˆEà×ÑœRŸY™Y¤s¨5£zÓ2´S¸Ó5FÑFÔGà×Ñ Õ&ð ô —=‘= §¡Ó/ˆØ)ˆ�Ñä—8‘8œS ›^¨aÑ/Ð0Ó1ˆð �[‹[à�L‰LÙÜ!Ÿ]™]¨4¯=©=¸Ñ+FÓGÜ!Ÿ]™]¨4¯=©=Ó9Ø%ôôð �"‰I×Ñ×#Ñ#à&Ø'6°yÑ'AÙ6?Ó @±i° ¨!£°iÑ @Ø$ñ	ôð �"‰I×Ñ×#Ñ#Ô%÷) ‰[ð1 1ô\ �8‰8�E‹?Ðùò !A÷ ‰[ús   Ä3A9HÆ,G?Æ8'HÇ?HÈH	)N)g      ð?)NNTF)rh   r<   Únumpyr   Ú r   r   r   Útypedr   r   r	   r
   r   Únetworkxr   ÚBaseExceptionÚEÚ
exceptionsr   r   rH   rP   r[   r]   rŽ   r�   r�   r®   r�   r   r   Ú<module>r¼      sÖ   ðÛ Û ã ç (Ñ (ß 7Ó 7Ý ðÛò#ó8kò\$óN3÷lcñ cðP !ØØØ"ñ@Øð@à�T‰>ð@ð �4‰-ð@ð ð	@ð
 ð@ð ˆR�Z‰ZÑó@óFJøðq ò õ .á	˜!Ó	…Bûðús   ªA2 Á2BÁ7B
Â
B