
    jXi                        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 	 	 	 	 	 d/d	ee   d
ee   dee
   dee
   dee
   f
dZd0dee
   dee
   fdZ	 d1de	dee
   dedefdZd2dee
   deej4                     fdZ	 d3de	dedefdZ	 	 	 d4de	de
dedefdZd2de	dee
   fd Z	 	 	 d5dededee
   fd!Zd6d"Z d2d#Z!d0d$Z"ejF                  fd%e	d&e	deej4                     fd'Z$d7d(Z%de	d)edeeejL                     ef   fd*Z'd+ Z(d,ejR                  dddfd-Z*d. Z+y# e$ r#ZddlmZ  ej*                  e      ZY dZ[!dZ[ww xY w)8zD
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                 X   t        | j                        dk(  ry|d}|d}|d}|d}|#t        j                  t        j
                        }t        | d      rVt        | j                        dkD  r>t        j                  t        | j                        t              }d|| j                  <   n.t        j                  t        | j                        t              }| j                  d	|z  z  g}|s| j                  j                  r| j                  j                  d
k(  rv| j                  j                  `t        | j                  j                        t        | j                        k(  r+|j!                  | j                  j                  d	|z  z         | j"                  d   }|sCt        j$                  |      | j                  j$                  k(  r|j!                  |d	|z  z         t        j&                  |      j)                         j+                  t        j,                        }t/        ||   d      \  }	}
t        j                  t        | j                        t        j,                        }|
||<   t        j0                  |      d   |	   }| j3                  ||       y)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                =/DATA/.local/lib/python3.12/site-packages/trimesh/grouping.pymerge_verticesr?      s   < 4==Q	
	..syy9 tW#djj/A"5XXc$--0=
!%
4:: WWS/t<
 }}M 123G
 KKKK	)KKNN&3t}}#55 	t{{~~Y78 kk*+G"((7+t}}/B/BBw"k/23 oog&,,.55bhh?G wz*t<DAq hhs4==):GGJ::j!!$Q'DdG4    min_lenmax_lenc                    t        j                  |       }|j                         }||   } | j                  j                  dk(  rKt        j
                  t        j                  t        j                  |             t        j                        }n| dd | dd k7  }t        j                  dt        j                  |      d   dz         }t        j                  t        |      t              }t        j                  t        j                  |t        |       gf            }||||||k\  z  }||||k  z  }t!        ||   ||         D 	
cg c]  \  }	}
||	|	|
z     }}	}
|S c c}
}	w )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   )r&   
asanyarrayargsortr   r,   greaterabsdiffr   zeror.   r6   r)   r!   r(   concatenatezip)valuesrA   rB   originalordernondupedupe_idxdupe_okdupe_lenr=   jgroupss               r>   grouprW   q   sS   * }}V$H Ee_F ||C **RVVBGGFO4chh?
 *s+yyBJJw/2Q67H ggc(m40G wwr~~x#f+&?@AH g1x7**Gx7**G-0'1BHWDU-VW-VTQeAQ -VFWM Xs   E%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              }|j                         |j                         }}d|dz
  z  dz
  }||k  r|| kD  rt        j                  t        |      t        j                        }|j                  |dz   z   j                  t        j                        }	t        |	      D ]#  \  }
}t        j                  |||
|z  z  |       % |S t        j                  t        j                   |j                  j"                  |j
                  d   z  f      }t        j$                  |      j'                  |      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   rY   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)rX   rY   rZ   as_int	precisiond_mind_max	thresholdhashablebitbangoffsetcolumnr   results                 r>   hashable_rowsr{      s   * 4yA~xx")),, $v.F 6<<A S&!+Q10Dfll1o!567	 zz|VZZ\u 9q=)Q.	 9)!3xxF299=H xx9q=199"))DG #,G"4xFY4F)GXV #5 O HHbggv||44v||AFGHE!!&)..u5==bAF %FLLMr@   c                    t        j                  |       } | j                  t         j                  k(  r| S | j                  j                  dv s| j
                  dk(  r| j                  t         j                        S | j                  j                  dk7  r| j                  t         j                        } |$t        j                  t        j                        }n8t        |t        t         j                  f      st        dt!        |       d      t        j"                  | d|z  z  dz
        j                  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   z%Digits must be `None` or `int`, not ``r   gư>)r&   rF   r   r4   r,   sizer3   float64r   r#   r   r$   
isinstancerd   integer	TypeErrortyper2   )rX   rY   s     r>   rc   rc      s    " ==D zzRXX	E	!TYY!^{{288$$	C	{{2::&~''		2bjj 12?V~QOPP
 88TBJ&$./66rxx@@r@   Freturn_indexreturn_inversec                     t        j                  | dd      \  }}}|j                         }|s|s||   S ||   g}|r|j                  ||          |r"|j                  |j                         |          |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&   uniquerG   r.   )rX   r   r   r   indexr    rP   rz   s           r>   unique_orderedr     sx    ,  YYt$tTFE7 MMOEe} Um_FeEl#emmog./Mr@   rN   	minlengthreturn_countsc                 6   t        j                  |       } t        | j                        dk7  s| j                  j
                  dk7  rt        d      	 t        j                  | |      }|j                  t              }t        j                  |      d   }|f}|r!t        j                  |      dz
  |    }||fz  }|r||   }	||	fz  }t        |      dk(  r|d   S |S # t        $ r0 t        j                  d       t        j                  | ||      cY S w xY w)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&   rF   r!   r0   r   r,   
ValueErrorbincountr   r   warningr   r3   r(   wherecumsum)
rN   r   r   r   counts
unique_binr   retr    unique_countss
             r>   unique_bincountr   A  s   B ]]6"F
6<<A!2!2c!9566	
Vy9 t$J XXj!!$F)C99Z(1,f5zv
3x1}1vJ9  
34yy>
 	
	
s   C 6DDc                    |t         j                  }nd| z  }t        j                  |       } t        j                  t        |       t              }d|d<   t        j                  | dd | dd z
        |kD  |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&   rF   r'   r!   r(   rI   )rX   rY   epsilonr   s       r>   
merge_runsr     s|    2 ~))&/==D88CIT*DDGvvd12hcr*+g5DH:r@   c                     t        j                  |       } t        | |      }t        j                  |dd      \  }}}|s|s| |   S | |   g}|r|j	                  |       |r|j	                  |       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&   rF   rc   r   r.   tuple)	rX   r   r   rY   rq   _junkr   r    rz   s	            r>   unique_floatr     sz     ==D$'FYYvDQUVE67>F|6l^Ffg=r@   c                 x    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   )rX   rY   r   rowss       r>   r5   r5     sG    , f-D ddKABOO 99TTB12FFr@   c                 
   |t        j                  |       }t        j                  |       } t        j                  | t        d      }|D ]5  }t        j
                  | |      }|j                  d      dk(  }||   ||<   7 |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)
    F)r   subokr   axis)r&   r   rF   
zeros_liker(   equalsum)rX   r   rz   valuetesttest_oks         r>   unique_value_in_rowr     sz    X ~4==D]]4t59Fxxe$((("a'w-w  Mr@   c                    t        | |      }|t        |      S |j                         }||   }|dd |dd k7  }t        j                  dt        j
                  |      d   dz         }t        j                  t        j                  |t        |      gf            |k(  }t        j                  ||   j                  d      |      t        j                  |      z   }||   }	|dk(  r|	j                  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   rE   r   )rE   r   )r{   rW   rG   r&   r.   r6   rJ   rL   r!   tilero   arange)
rX   require_countrY   rv   rP   duperR   start_okrV   
groups_idxs
             r>   
group_rowsr   #  s    < T&1H X EH AB<8CR=(D yyBJJt,Q/!34H wwr~~x#h-&ABC}THWWXh'//8-H299L F vJ!!"%%r@   abc                    t        j                  | t         j                        } t        j                  |t         j                        }| j                  d| j                  fg| j
                  d   z        j                         }|j                  d|j                  fg|j
                  d   z        j                         } |||      j                  | j                        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&   rF   r4   rn   r   r0   ravelro   )r   r   	operationavbvs        r>   boolean_rowsr   _  s    , 	arxx(A
arxx(A	
"agg!''!*,	-	3	3	5B	
"agg!''!*,	-	3	3	5BR!!!''*222qwwqzBBr@   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&   rF   r   floatr   vector_hemispherevector_to_sphericalgroup_distancespherical_to_vector)vectorsangleinclude_negative	sphericalanglesrV   new_vectorss          r>   group_vectorsr   }  so    . mmG2::6G%LE((1((1I#Iu5NFF**62Kr@   distancec                    t        j                  | t         j                        } t        j                  t	        |       t
              }t        |       }g }g }t        |       D ]  \  }}||   rt        j                  |j                  ||      t         j                        }|||       }d||<   |j                  t        j                  | |   d             |j                  |        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&   rF   r   r'   r!   r(   r   ri   ra   query_ball_pointr4   r.   median)	rN   r   consumedtreer   rV   r   r   rW   s	            r>   r   r     s    , ]]64FxxF40H6?D FF!&)uE?..uh?rxxPx&'biiuA67e * 88FV##r@   c                 p    ddl m} t        |       }|j                  |d      }|j	                  |      }|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   pairsrV   s         r>   clustersr     s<    " 6?D v9=E''.FMr@   r   c           	         t        | |      } t        j                  t        |             }d|j                  d<   |dd | dd | dd k7     }t        j
                  t        |      dz   t              }t        |       |d<   ||dd |dd |dd z
  }	t        j                  |	|k\  |	|k        }
|rt        j                  |
| |dd          }
t        |
      D cg c]  \  }}|s	|||   ||dz        }}}|rD| d	   | d   k7  r|S |rt        | d	         s|S t        |      dk(  rt        |d	         t        |       k(  r|S t        |      d	kD  xr |d	   d	   d	k(  }t        |      d	kD  xr |d   d   t        |       dz
  k(  }|r3|r1t        j                  |d   |d	         |d	<   |j                          |S |	d	   |	d   z   }||k  s||kD  r|S t        j                  t        j                  |d
   |d         t        j                  |d	   |d               }|r||d	<   |S |r||d<   |S |j                  |       |S c c}}w )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]   Fr`   r   NrE   r   r   r   )rc   r&   r   r!   rp   r'   rd   logical_andri   r(   r.   pop)rX   rA   rB   wraprY   only_nonzeror   r6   inflinfl_leninfl_okr=   okblocksfirstlastcombined	new_blocks                     r>   r   r     s   2 V,D YYs4y!F %FLLQRjabT#2Y./G88CL1$C0D4yDHD2J ABx$s)#H nnX0(g2EFG ..$tCRy/: :C79KR9K2rfT!WtAE{+9KFR7d2hM T!WM v;!F1I#d) ;M Fa5F1IaLA$56{QD6":b>c$i!m#D T		&*fQi8F1IJJL. M)  {Xb\1H'!X%7				$r(DH-ryya$q'/JI %q	 M &r
 M i(Mg Ss   
I $I c                     t        j                  || f      }| |   } ||   }t        j                  t        |       d      }d|d<   | dd | dd k7  |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!   )rV   rX   rP   r   s       r>   	group_minr   N  sk    & JJf~&EE]F;DHHS[&)EE!Hqr
fSbk)E!"I;r@   )NNNNN)NN)NT)N)FF)r   FF)FFN)NF)g-C6?F),__doc__numpyr&   r   r   	constantsr   r   typedr   r   r	   r
   r   r   r   scipy.spatialr   BaseExceptionEr   ExceptionWrapperr(   r?   rW   r{   r4   rc   r   r   r   r   r5   r   r   intersect1dr   r   r   r   r   infr   r    r@   r>   <module>r      sr      Q Q Q-% !%!%'+%)#'V5~V5 V5 G$	V5
 '"V5  V5r68G, 6hw>O 6t JN?
?%g.?BF??D&Ax0 &AGBHH<M &AT IN)
)#')AE)\  	DDD D 	DN#Y #(9 #P   $	  W	8GD4n9z +-..CCCRXXC< F($($!'($
72::()($V: BFFtRW cL}  - )j))!,G-s   D, ,E1EE