
    l0jh                     p   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 	 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	 	 	 	 	 d.d	ee         d
ee         dee
         dee
         dee
         f
dZd/dee
         dee
         fdZ	 d0de	dee
         dedefdZd1dee
         deej                 fdZ	 d2de	dedefdZ	 	 	 d3de	de
dedefd Zd1de	dee
         fd!Z	 	 	 d4dededee
         fd"Zd5d#Zd1d$Zd/d%Zej         fd&Z!d6d(Z"d) Z#d* Z$d+ej%        dddfd,Z&d- Z'dS )7zD
grouping.py
-------------

Functions for grouping values and rows.
    N   )util)logtol)	ArrayLikeIntegerNDArrayOptional)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                S/home/wildlama/miniconda3/envs/lam/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  rD   ).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+   r3   r&   r   r%   concatenatezip)
valuesr>   r?   originalnondupedupe_idxdupe_okdupe_lengroupsrG   s
            @r;   grouprX   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   rZ   r   r   r   @   )outrB   F	WRITEABLE)r   r#   arrayuint64float_to_intr-   intfloorminmaxr$   Tr0   	enumeratebitwise_xorr   voiditemsizeascontiguousarrayviewreshapeflags)rY   rZ   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                  }n0t          |t          t           j        f          s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   rA   Nz4Digits must be `None` or `int`, not `{type(digits)}`r   gư>)r#   rI   r   r1   r)   sizer0   float64r   r    r   r!   
isinstancere   integer	TypeErrorr/   )rY   rZ   s     r;   rd   rd      s    " =D zRX	E	!	!TY!^^{{28$$$	C		{{2:&&~'	22bj 122 PNOOO
 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#   uniquerJ   r+   )rY   r   r   r   indexr   rG   r{   s           r;   unique_orderedr     s    ,  Yt$tTTTFE7 MMOOE  e} Um_F $eEl### 0emmoog.///Mr=   rQ   	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#   rI   r   r-   r   r)   
ValueErrorbincountr   r   warningr   r0   r%   wherecumsum)
rQ   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   rB   )r   r!   r#   rI   r$   r   r%   rL   )rY   rZ   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#   rI   rd   r   r+   tuple)	rY   r   r   rZ   rr   _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
    r^   Tr   r   N)r|   r   r#   r   )rY   rZ   r   rowss       r;   r2   r2     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   rI   
zeros_liker%   equalsum)rY   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.
    r^   Nr   rB   r   )rB   r   )r|   rX   rJ   r#   r+   r3   rM   rO   r   tilerp   arange)
rY   require_countrZ   rw   rG   duperT   start_okrW   
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=   c                    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) array containing rows in both a and b
    r    r   rB   )r#   rI   r1   ro   r   r-   ravelrp   )ab	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#   rI   r   floatr   vector_hemispherevector_to_sphericalgroup_distancespherical_to_vector)vectorsangleinclude_negative	sphericalanglesrW   new_vectorss          r;   group_vectorsr   z  s{    . mG2:666G%LLE 2(11(11I#Iu55NFF*622Kr=   c                    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 groups of points which have neighbours closer than radius,
    where no two points in a group are farther than distance apart.

    Parameters
    ---------
    points :   (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#   rI   r   r$   r   r%   r   rj   rb   query_ball_pointr1   r+   median)	rQ   distanceconsumedtreer   rW   r   r   rX   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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   pairsrW   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
    r^   Fra   r   NrB   r   r   c                 L    g | ] \  }}||         |d z                     !S )r   rD   )rE   r:   okr   infls      r;   rH   zblocks.<locals>.<listcomp>  s8    RRR2rRfT!WtAE{*+RRRr=   r   )rd   r#   r   r   rq   r$   re   logical_andrj   r%   r+   pop)rY   r>   r?   wraprZ   only_nonzeror3   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   NrB   )r#   lexsortr$   r   )rW   rY   rG   r   s       r;   	group_minr   H  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
   scipy.spatialr   BaseExceptionEr   ExceptionWrapperr%   r<   rX   r|   r1   rd   r   r   r   r   r2   r   r   intersect1dr   r   r   r   infr   r   rD   r=   r;   <module>r      s                      8 8 8 8 8 8 8 8 8 8 8 8-%%%%%%% - - - )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x "$ C C C C6       F%$ %$ %$P  : BFtRW c c c cL    s   ) AA		A