
    TiXi                        d Z ddlZddlmZ ddlmZmZ ddlm	Z	m
Z
mZmZmZmZmZ 	 ddlmZ n(# e$ r ZddlmZ  ej        e          ZY dZ[ndZ[ww xY w	 	 	 	 	 d1d	ee         d
ee         dee
         dee
         dee
         f
dZd2dee
         dee
         fdZ	 d3de	dee
         dedefdZd4dee
         deej                 fdZ	 d5de	dedefdZ	 	 	 d6de	de
dedefd Zd4de	dee
         fd!Z	 	 	 d7dededee
         fd"Zd8d#Z d4d$Z!d2d%Z"ej#        fd&e	d'e	deej                 fd(Z$d9d*Z%de	d+edeeej&                 ef         fd,Z'd- Z(d.ej)        dddfd/Z*d0 Z+dS ):zD
grouping.py
-------------

Functions for grouping values and rows.
    N   )util)logtol)	ArrayLikeIntegerNDArrayNumberOptionalSequenceTuple)cKDTree)
exceptions	merge_tex
merge_normdigits_vertexdigits_norm	digits_uvc                    t          | j                  dk    rdS |d}|d}|d}|d}|t          j        t          j                  }t          | d          rPt          | j                  dk    r8t          j	        t          | j                  t                    }d|| j        <   n-t          j        t          | j                  t                    }| j        d	|z  z  g}|s|| j        j        rp| j        j        d
k    r`| j        j        Tt          | j        j                  t          | j                  k    r%|                    | j        j        d	|z  z             | j        d         }|s=t          j        |          | j        j        k    r|                    |d	|z  z             t          j        |                                                              t          j                  }t/          ||         d          \  }	}
t          j	        t          | j                  t          j                  }|
||<   t          j        |          d         |	         }|                     ||           dS )a  
    Removes duplicate vertices, grouped by position and
    optionally texture coordinate and normal.

    Parameters
    -------------
    mesh : Trimesh object
      Mesh to merge vertices on
    merge_tex : bool
      If True textured meshes with UV coordinates will
      have vertices merged regardless of UV coordinates
    merge_norm : bool
      If True, meshes with vertex normals will have
      vertices merged ignoring different normals
    digits_vertex : None or int
      Number of digits to consider for vertex position
    digits_norm : int
      Number of digits to consider for unit normals
    digits_uv : int
      Number of digits to consider for UV coordinates
    r   NF      facesdtypeT
   texturevertex_normals)
keep_order)maskinverse)lenverticesr   decimal_to_digitsr   mergehasattrr   npzerosboolonesvisualdefinedkinduvappend_cacheshapecolumn_stackroundastypeint64unique_rowsnonzeroupdate_vertices)meshr   r   r   r   r   
referencedstackednormalsuir    r   s                J/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/grouping.pymerge_verticesr?      sY   < 4=Q	
	.sy99 tW =#dj//A"5"5Xc$-00===
!%
4: WS//t<<<
 }M 123G
 	9K	9 K	))KN&3t}#5#555 	t{~Y7888 k*+G 4"(7++t}/BBBw"k/2333 og&&,,..55bh??G wz*t<<<DAq hs4=)):::GGJ:j!!!$Q'DdG44444    min_lenmax_lenc                   	 t          j        |           }|                                	|	         } | j        j        dk    rDt          j        t          j        t          j        |                     t          j	                  }n| dd         | dd         k    }t          j
        dt          j        |          d         dz             }t          j        t          |          t                    }t          j        t          j        |t          |           gf                    }|||	|||k    z  }|	|||k    z  }	fdt!          ||         ||                   D             }|S )a  
    Return the indices of values that are identical

    Parameters
    ----------
    values : (n,) int
      Values to group
    min_len : int
      The shortest group allowed
      All groups will have len >= min_length
    max_len : int
      The longest group allowed
      All groups will have len <= max_length

    Returns
    ----------
    groups : sequence
      Contains indices to form groups
      IE [0,1,0,1] returns [[0,2], [1,3]]
    fr   Nr   r   c                 0    g | ]\  }}|||z            S  rG   ).0r=   jorders      r>   
<listcomp>zgroup.<locals>.<listcomp>   s*    WWWTQeAQK WWWr@   )r&   
asanyarrayargsortr   r,   greaterabsdiffr   zeror.   r6   r)   r!   r(   concatenatezip)
valuesrA   rB   originalnondupedupe_idxdupe_okdupe_lengroupsrJ   s
            @r>   groupr[   q   sY   * }V$$H Ee_F |C *RVBGFOO44ch??
 *ss+yBJw//2Q677H gc(mm4000G wr~x#f++&?@@AAH g1x7**Gx7**GWWWWS'1BHWDU-V-VWWWFMr@   Tdatadigits	allow_intreturnc                    t          |           dk    r t          j        g t          j                  S t	          | |          }t          |j                  dk    r|S |r$t          |j                  dk    r|j        d         dk    rt          t          j        d|j        d         z                      }|                                |	                                }}d|dz
  z  dz
  }||k     r|| k    rt          j
        t          |          t          j                  }|j        |dz   z                       t          j                  }	t          |	          D ]"\  }
}t          j        |||
|z  z  |           #|S t          j        t          j        |j        j        |j        d         z  f          }t          j        |                              |                              d	          }d
|j        d<   |S )a  
    We turn our array into integers based on the precision
    given by digits and then put them in a hashable format.

    Parameters
    ---------
    data : (n, m) array
      Input data
    digits : int or None
      How many digits to add to hash if data is floating point
      If None, tol.merge will be used

    Returns
    ---------
    hashable : (n,)
      May return as a `np.void` or a `np.uint64`
    r   r   r]   r   r   r   @   )outrE   F	WRITEABLE)r!   r&   arrayuint64float_to_intr0   intfloorminmaxr'   Tr3   	enumeratebitwise_xorr   voiditemsizeascontiguousarrayviewreshapeflags)r\   r]   r^   as_int	precisiond_mind_max	thresholdhashablebitbangoffsetcolumnr   results                 r>   hashable_rowsr      s   * 4yyA~~x"),,,, $v...F 6<A  S&&!++Q10D0Dfl1o!56677	 zz||VZZ\\u 9q=)Q.	 9)!3!3xF29===H x9q=199")DDG #,G"4"4 W WxFY4F)GXVVVVVO Hbgv|4v|AFGHHE!&))..u55==bAAF %FLMr@   c                 ^   t          j        |           } | j        t           j        k    r| S | j        j        dv s| j        dk    r|                     t           j                  S | j        j        dk    r|                     t           j                  } |t          j	        t          j                  }nAt          |t          t           j        f          s t          dt!          |           d          t          j        | d|z  z  dz
                                t           j                  S )	a+  
    Given a numpy array of float/bool/int, return as integers.

    Parameters
    -------------
    data :  (n, d) float, int, or bool
      Input data
    digits : float or int
      Precision for float conversion

    Returns
    -------------
    as_int : (n, d) int
      Data as integers
    iubr   rD   Nz%Digits must be `None` or `int`, not ``r   gư>)r&   rL   r   r4   r,   sizer3   float64r   r#   r   r$   
isinstancerh   integer	TypeErrortyper2   )r\   r]   s     r>   rg   rg      s    " =D zRX	E	!	!TY!^^{{28$$$	C		{{2:&&~'	22bj 122 QOVOOOPPP
 8TBJ&$.//66rx@@@r@   Freturn_indexreturn_inversec                 &   t          j        | dd          \  }}}|                                }|s
|s||         S ||         g}|r|                    ||                    |r-|                    |                                |                    |S )aL  
    Returns the same as np.unique, but ordered as per the
    first occurrence of the unique value in data.

    Examples
    ---------
    In [1]: a = [0, 3, 3, 4, 1, 3, 0, 3, 2, 1]

    In [2]: np.unique(a)
    Out[2]: array([0, 1, 2, 3, 4])

    In [3]: trimesh.grouping.unique_ordered(a)
    Out[3]: array([0, 3, 4, 1, 2])
    Tr   r   )r&   uniquerM   r.   )r\   r   r   r   indexr    rJ   r~   s           r>   unique_orderedr     s    ,  Yt$tTTTFE7 MMOOE  e} Um_F $eEl### 0emmoog.///Mr@   rT   	minlengthreturn_countsc                 P   t          j        |           } t          | j                  dk    s| j        j        dk    rt          d          	 t          j        | |          }n;# t          $ r. t          j
        d           t          j        | ||          cY S w xY w|                    t                    }t          j        |          d         }|f}|r#t          j        |          dz
  |          }||fz  }|r||         }	||	fz  }t          |          dk    r|d         S |S )ai  
    For arrays of integers find unique values using bin counting.
    Roughly 10x faster for correct input than np.unique

    Parameters
    --------------
    values : (n,) int
      Values to find unique members of
    minlength : int
      Maximum value that will occur in values (values.max())
    return_inverse : bool
      If True, return an inverse such that unique[inverse] == values
    return_counts : bool
      If True, also return the number of times each
      unique item appears in values

    Returns
    ------------
    unique : (m,) int
      Unique values in original array
    inverse : (n,) int, optional
      An array such that unique[inverse] == values
      Only returned if return_inverse is True
    counts : (m,) int, optional
      An array holding the counts of each unique item in values
      Only returned if return_counts is True
    r   r=   zinput must be 1D integers!)r   zcasting failed, falling back!)r   r   r   )r&   rL   r!   r0   r   r,   
ValueErrorbincountr   r   warningr   r3   r(   wherecumsum)
rT   r   r   r   counts
unique_binr   retr    unique_countss
             r>   unique_bincountr   A  sP   B ]6""F
6<A!2c!9!95666	
Vy999 
 
 
3444y>
 
 
 	
 	
 	
	
 t$$J Xj!!!$F)C 9Z((1,f5z  v
3xx1}}1vJs   A$ $5BBc                    |t           j        }nd| z  }t          j        |           } t          j        t          |           t                    }d|d<   t          j        | dd         | dd         z
            |k    |dd<   | |         S )aW  
    Merge duplicate sequential values. This differs from unique_ordered
    in that values can occur in multiple places in the sequence, but
    only consecutive repeats are removed

    Parameters
    -----------
    data: (n,) float or int

    Returns
    --------
    merged: (m,) float or int

    Examples
    ---------
    In [1]: a
    Out[1]:
    array([-1, -1, -1,  0,  0,  1,  1,  2,  0,
            3,  3,  4,  4,  5,  5,  6,  6,  7,
            7,  8,  8,  9,  9,  9])

    In [2]: trimesh.grouping.merge_runs(a)
    Out[2]: array([-1,  0,  1,  2,  0,  3,  4,  5,  6,  7,  8,  9])
    Nr   r   Tr   r   rE   )r   r$   r&   rL   r'   r!   r(   rO   )r\   r]   epsilonr   s       r>   
merge_runsr     s    2 ~)&/=D8CIIT***DDGvd122hcrc*++g5DH:r@   c                 $   t          j        |           } t          | |          }t          j        |dd          \  }}}|s
|s| |         S | |         g}|r|                    |           |r|                    |           t          |          S )z
    Identical to the numpy.unique command, except evaluates floating point
    numbers, using a specified number of digits.

    If digits isn't specified, the library default TOL_MERGE will be used.
    Tr   )r&   rL   rg   r   r.   tuple)	r\   r   r   r]   ru   _junkr   r    r~   s	            r>   unique_floatr     s     =D$''FYvDQUVVVE67 > F|6l^F f g==r@   c                     t          | |          }|rt          |dd          dd         S t          j        |dd          dd         S )a  
    Returns indices of unique rows. It will return the
    first occurrence of a row that is duplicated:
    [[1,2], [3,4], [1,2]] will return [0,1]

    Parameters
    ---------
    data : (n, m) array
      Floating point data
    digits : int or None
      How many digits to consider

    Returns
    --------
    unique :  (j,) int
      Index in data which is a unique row
    inverse : (n,) int
      Array to reconstruct original
      Example: data[unique][inverse] == data
    ra   Tr   r   N)r   r   r&   r   )r\   r]   r   rowss       r>   r5   r5     sa    , f---D  PddKKKABBOO 9TTBBB122FFr@   c                    |t          j        |           }t          j        |           } t          j        | t          d          }|D ]<}t          j        | |          }|                    d          dk    }||         ||<   =|S )a  
    For a 2D array of integers find the position of a
    value in each row which only occurs once.

    If there are more than one value per row which
    occur once, the last one is returned.

    Parameters
    ----------
    data :   (n, d) int
      Data to check values
    unique : (m,) int
      List of unique values contained in data.
      Generated from np.unique if not passed

    Returns
    ---------
    result : (n, d) bool
      With one or zero True values per row.


    Examples
    -------------------------------------
    In [0]: r = np.array([[-1,  1,  1],
                          [-1,  1, -1],
                          [-1,  1,  1],
                          [-1,  1, -1],
                          [-1,  1, -1]], dtype=np.int8)

    In [1]: unique_value_in_row(r)
    Out[1]:
           array([[ True, False, False],
                  [False,  True, False],
                  [ True, False, False],
                  [False,  True, False],
                  [False,  True, False]], dtype=bool)

    In [2]: unique_value_in_row(r).sum(axis=1)
    Out[2]: array([1, 1, 1, 1, 1])

    In [3]: r[unique_value_in_row(r)]
    Out[3]: array([-1,  1, -1,  1,  1], dtype=int8)
    NF)r   subokr   axis)r&   r   rL   
zeros_liker(   equalsum)r\   r   r~   valuetesttest_oks         r>   unique_value_in_rowr     s    X ~4=D]4t5999F ( (xe$$(((""a'w-wMr@   c                 N   t          | |          }|t          |          S |                                }||         }|dd         |dd         k    }t          j        dt          j        |          d         dz             }t          j        t          j        |t          |          gf                    |k    }t          j	        ||         
                    d          |          t          j        |          z   }||         }	|dk    r|	
                    d          S |	S )a  
    Returns index groups of duplicate rows, for example:
    [[1,2], [3,4], [1,2]] will return [[0,2], [1]]


    Note that using require_count allows numpy advanced
    indexing to be used in place of looping and
    checking hashes and is ~10x faster.


    Parameters
    ----------
    data : (n, m) array
      Data to group
    require_count : None or int
      Only return groups of a specified length, eg:
      require_count =  2
      [[1,2], [3,4], [1,2]] will return [[0,2]]
    digits : None or int
    If data is floating point how many decimals
    to consider, or calculated from tol.merge

    Returns
    ----------
    groups : sequence (*,) int
      Indices from in indicating identical rows.
    ra   Nr   rE   r   )rE   r   )r   r[   rM   r&   r.   r6   rP   rR   r!   tilers   arange)
r\   require_countr]   rz   rJ   duperW   start_okrZ   
groups_idxs
             r>   
group_rowsr   #  s"   < T&111H X EH ABB<8CRC=(D yBJt,,Q/!344H wr~x#h--&ABBCC}THWXh'//88-HH29L L F vJ!!"%%%r@   abc                    t          j        | t           j                  } t          j        |t           j                  }|                     d| j        fg| j        d         z                                            }|                    d|j        fg|j        d         z                                            } |||                              | j                                      d| j        d                   S )a  
    Find the rows in two arrays which occur in both rows.

    Parameters
    ---------
    a: (n, d) int
        Array with row vectors
    b: (m, d) int
        Array with row vectors
    operation : function
        Numpy boolean set operation function:
          -np.intersect1d
          -np.setdiff1d

    Returns
    --------
    shared : (p, d) int64
       Array containing requested rows in both a and b
    r    r   rE   )r&   rL   r4   rr   r   r0   ravelrs   )r   r   	operationavbvs        r>   boolean_rowsr   _  s    , 	arx(((A
arx(((A	
"ag!'!*,	-	-	3	3	5	5B	
"ag!'!*,	-	-	3	3	5	5B9R!!!'**222qwqzBBBr@   -C6?c                 
   t          j        | t           j                  } t          |          }|rt	          j        |           } t	          j        |           }t          ||          \  }}t	          j        |          }||fS )a  
    Group vectors based on an angle tolerance, with the option to
    include negative vectors.

    Parameters
    -----------
    vectors : (n,3) float
        Direction vector
    angle : float
        Group vectors closer than this angle in radians
    include_negative : bool
        If True consider the same:
        [0,0,1] and [0,0,-1]

    Returns
    ------------
    new_vectors : (m,3) float
        Direction vector
    groups : (m,) sequence of int
        Indices of source vectors
    r   )	r&   rL   r   floatr   vector_hemispherevector_to_sphericalgroup_distancespherical_to_vector)vectorsangleinclude_negative	sphericalanglesrZ   new_vectorss          r>   group_vectorsr   }  s{    . mG2:666G%LLE 2(11(11I#Iu55NFF*622Kr@   distancec                 8   t          j        | t           j                  } t          j        t	          |           t
                    }t          |           }g }g }t          |           D ]\  }}||         rt          j        |	                    ||          t           j
                  }|||                   }d||<   |                    t          j        | |         d                     |                    |           t          j        |          |fS )a  
    Find non-overlapping groups of points where no two points in a
    group are farther than 2*distance apart.

    Parameters
    ---------
    values : (n, d) float
        Points of dimension d
    distance : float
        Max distance between points in a cluster

    Returns
    ----------
    unique : (m, d) float
        Median value of each group
    groups : (m) sequence of int
        Indexes of points that make up a group

    r   Tr   r   )r&   rL   r   r'   r!   r(   r   rm   re   query_ball_pointr4   r.   median)	rT   r   consumedtreer   rZ   r   r   r[   s	            r>   r   r     s   , ]6444FxF4000H6??D FF!&))  uE? 	..uh??rxPPPx&'biuA666777e8FV##r@   c                     ddl m} t          |           }|                    |d          }|                    |          }|S )aJ  
    Find clusters of points which have neighbours closer than radius

    Parameters
    ---------
    points : (n, d) float
        Points of dimension d
    radius : float
        Max distance between points in a cluster

    Returns
    ----------
    groups : (m,) sequence of int
        Indices of points in a cluster

    r   )graphndarray)routput_type)r   r   r   query_pairsconnected_components)pointsradiusr   r   pairsrZ   s         r>   clustersr     sS    " 6??D v9==E''..FMr@   r   c                 j   t          | |          } t          j        t          |                     dj        d<   dd         | dd         | dd         k             }t          j        t          |          dz   t                    t          |           d<   |dd<   dd         dd         z
  }t          j        ||k    ||k              }|r#t          j        || dd                            }fd	t          |          D             }	|r| d
         | d         k    r|	S |rt          | d
                   s|	S t          |	          dk    r(t          |	d
                   t          |           k    r|	S t          |	          d
k    o|	d
         d
         d
k    }
t          |	          d
k    o!|	d         d         t          |           dz
  k    }|
r;|r9t          j
        |	d         |	d
                   |	d
<   |	                                 n|d
         |d         z   }||k     s||k    r|	S t          j
        t          j        d         d                   t          j        d
         d                             }|
r||	d
<   n|r||	d<   n|	
                    |           |	S )aZ  
    Find the indices in an array of contiguous blocks
    of equal values.

    Parameters
    ------------
    data : (n,) array
      Data to find blocks on
    min_len : int
      The minimum length group to be returned
    max_len : int
      The maximum length group to be retuurned
    wrap : bool
      Combine blocks on both ends of 1D array
    digits : None or int
      If dealing with floats how many digits to consider
    only_nonzero : bool
      Only return blocks of non- zero values

    Returns
    ---------
    blocks : (m) sequence of (*,) int
      Indices referencing data
    ra   Frd   r   NrE   r   r   c                 L    g | ] \  }}||         |d z                     !S )r   rG   )rH   r=   okr   infls      r>   rK   zblocks.<locals>.<listcomp>  s8    RRR2rRfT!WtAE{*+RRRr@   r   )rg   r&   r   r!   rt   r'   rh   logical_andrm   r(   r.   pop)r\   rA   rB   wrapr]   only_nonzeror6   infl_leninfl_okblocksfirstlastcombined	new_blockr   r   s                 @@r>   r   r     s   2 V,,,D Ys4yy!!F %FLQRRjabbT#2#Y./G8CLL1$C000D4yyDHD2J ABBx$ss)#H nX0(g2EFFG ; .$tCRCy/:: SRRRR79K9KRRRF /)7d2hM  	T!W 	M v;;!F1I#d)) ; ;M Fa5F1IaLA$56{{QD6":b>c$ii!m#D  	)T 	)	&*fQi88F1IJJLLLL  {Xb\1H'!!X%7%7		$r(DH--rya$q'/J/J I  	)%q		 )&r

 i(((Mr@   c                     t          j        || f          }| |         } ||         }t          j        t          |           d          }d|d<   | dd         | dd         k    |dd<   ||         S )a{  
    Given a list of groups find the minimum element of data
    within each group

    Parameters
    -----------
    groups : (n,) sequence of (q,) int
        Indexes of each group corresponding to each element in data
    data : (m,)
        The data that groups indexes reference

    Returns
    -----------
    minimums : (n,)
        Minimum value of data per group

    r(   Tr   r   NrE   )r&   lexsortr'   r!   )rZ   r\   rJ   r   s       r>   	group_minr   N  su    & Jf~&&EE]F;DHS[[&))EE!Hqrr
fSbSk)E!""I;r@   )NNNNN)NN)NT)N)FF)r   FF)FFN)NF)r   F),__doc__numpyr&   r   r   	constantsr   r   typedr   r   r	   r
   r   r   r   scipy.spatialr   BaseExceptionEr   ExceptionWrapperr(   r?   r[   r   r4   rg   r   r   r   r   r5   r   r   intersect1dr   r   r   r   r   infr   r   rG   r@   r>   <module>r      s@                      Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q Q-%%%%%%% - - - )j)!,,GGGGGG- !%!%'+%)#'V5 V5~V5 V5 G$	V5
 '"V5  V5 V5 V5 V5r6 68G, 6hw>O 6 6 6 6t JN? ?
?%g.?BF?? ? ? ?D&A &Ax0 &AGBH<M &A &A &A &AT IN) )
)#')AE) ) ) )\  	D DDD D 	D D D DN# #Y #(9 # # # #P   $	   W	   8G G G GD4 4 4 4n9 9 9 9z +-.C CCCRXC C C C<       F($($!'($
72:()($ ($ ($ ($V  : BFtRW c c c cL    s   / AAA