
    j9                         d dl ZddlmZ ddlmZ ddlmZ 	 d dlZ	d ZddZdd	Zd
 Zej$                  dfdedefdZd ZddZ	 ddZddZy# e
$ r"ZddlmZ  ej                  e      Z	Y dZ[VdZ[ww xY w)    N   )util)log)NDArray)
exceptionsc                     t        |g d      }| 5t        j                  |t        j                  | d            dd  |dddf<   |S )a  
    Given the origin and normal of a plane find the transform
    that will move that plane to be coplanar with the XY plane.

    Parameters
    ----------
    origin : (3,) float
        Point that lies on the plane
    normal : (3,) float
        Vector that points along normal of plane

    Returns
    ---------
    transform: (4,4) float
        Transformation matrix to move points onto XY plane
    )r   r   r   Nr      )align_vectorsnpdotappend)originnormal	transforms      =/DATA/.local/lib/python3.12/site-packages/trimesh/geometry.pyplane_transformr      sN    " fi0IFF9bii.BCBQGG	"1"a%    c                    t        j                  | t         j                        } t        j                  |t         j                        }| j                  dk7  s|j                  dk7  rt	        d      t         j
                  j                  | j                  d            d   }t         j
                  j                  |j                  d            d   }t         j
                  j                  |      dk  r|dddfxx   dz  cc<   t         j
                  j                  |      dk  r|dddfxx   dz  cc<   t        j                  d	      }|j                  |j                        |dd
dd
f<   |rbt        j                  |d   |d         }t        j                  t        j                  |dd            }|dk  r|t         j                  z  }||fS |S )a  
    Find the rotation matrix that transforms one 3D vector
    to another.

    Parameters
    ------------
    a : (3,) float
      Unit vector
    b : (3,) float
      Unit vector
    return_angle : bool
      Return the angle between vectors or not

    Returns
    -------------
    matrix : (4, 4) float
      Homogeneous transform to rotate from `a` to `b`
    angle : float
      If `return_angle` angle in radians between `a` and `b`

    dtype)r	   zvectors must be (3,)!r   r   Nr            r	         ?gh㈵)r   arrayfloat64shape
ValueErrorlinalgsvdreshapedeteyer   Tarccosclippi)abreturn_angleaubumatrixr   angles           r   r
   r
   '   sh   , 	"**%A
"**%Aww$!''T/011 
qyy)	*1	-B	qyy)	*1	-B	yy}}R1
1b5	T		yy}}R1
1b5	T	 VVAYFVVBDD\F2A2rr6N ffRUBqE"		"''#tS12;RUUNEu}Mr   c                 $   t        j                  | t         j                        } | ddg df   j                  d      }|rOt        j                  t        j
                  t        |             d      j                  j                  d      }||fS |S )a  
    Given a list of faces (n,3), return a list of edges (n*3,2)

    Parameters
    -----------
    faces : (n, 3) int
      Vertex indices representing faces

    Returns
    -----------
    edges : (n*3, 2) int
      Vertex indices representing edges
    N)r   r   r      r1   r   )r   r1   )r	   r   r   )r   
asanyarrayint64r"   tilearangelenr%   )facesreturn_indexedges
face_indexs       r   faces_to_edgesr;   \   sv     MM%*E !''(009EWWRYYs5z2F;==EEbI
j  Lr   c                    t        j                  | t         j                        } t        |       dk(  rt        j                  g       S t        j                  | d      r| j                  d      } n!t        j                  | d      st        d      t        j                  | dddf   | dddf         }t        j                  |d	d
      }t        j                  t        j                  |            }|S )z
    Find the angles between pairs of unit vectors.

    Parameters
    ----------
    pairs : (n, 2, 3) float
      Unit vector pairs

    Returns
    ----------
    angles : (n,) float
      Angles between vectors in radians
    r   r   r1   r	   )r   r1   r	   )r   r1   r=   zpairs must be (n,2,(2|3))!Nr   r   r   )r   r2   r   r6   r   r   is_shaper"   r   diagonal_dotr'   absr&   )pairsdotsangless      r   vector_anglerD   v   s     MM%rzz2E
5zQxx|	uf	%j)]]5/2566 U1a4[%1+6D774s#DVVBIIdO$FMr   Tuse_fanreturnc                 n   t        |       dk(  rt        j                  d|      S 	 t        j                  | |      } t        | j                        dk(  r#| j                  d   dk(  r| j                  |      S t        | j                        dk(  rJ| j                  d   dk(  r8t        j                  | ddg df   | ddg d	f   f      j                  |      S t        j                  | D cg c]  }t        |       c}t        j                        }t        j                  t        j                  |dk(        d   D cg c]  }| |   	 c}t        j                        }t        j                  t        j                  |dk(        d   D cg c]  }| |   	 c}t        j                        }|r,t        j                  |dkD        d   D cg c]  }| |   	 }}ng }t        |      dk(  rt        |      dk(  r|j                  |      S t        |      dkD  rt        j                  |      }t        |      dkD  r)t        j                  |ddg df   |ddg d	f   f      }t        j                  |||g      j                  |      S # t        $ r Y w xY wc c}w c c}w c c}w c c}w )
a  
    Given an array of quad faces return them as triangle faces,
    also handles pure triangles and mixed triangles and quads.

    Parameters
    -----------
    quads: (n, 4) int
      Vertex indices of quad faces.
    dtype
      Data type requested for the return
    use_fan
      Triangulate holes larger than quads with fans,
      which may be wrong if the holes are non-convex

    Returns
    -----------
    faces : (m, 3) int
      Vertex indices of triangular faces.
    r   r   r1   r   r	   r   N)r   r   r1   )r1   r	   r   )r6   r   zerosr   r   astypevstackr   r3   nonzeror   triangle_fans_to_facesvstack_empty)quadsr   rE   ilengthstriquadpolys           r   triangulate_quadsrT      sG   * 5zQxx'' e,u{{q U[[^q%8<<&&u{{q U[[^q%899eAyL15I3FGHOOPUVV hh.1A.bhh?G ((bjjA&>q&AB&AE!H&AB"((
SC88rzz'Q,'?'BC'B!U1X'BC288TD"$**Wq["9!"<="<Qa"<= 
4yA~#d)q.zz%  
4y1}**40
4y1}yy$q)|,d1i<.@ABc4./66u==;   / CC >s1   AJ 9A!J .J#J(J-J2	J J c                 V   	 t        j                  |j                         |       }t        |      | k(  sJ |j                         | k  sJ t        j                  dt        j                  |      dd       }t        j                  |j                               |dddf   z   }|||z   dddf   k\  j                  t         j                         }	 t        j                  j!                  t        |      t"        	      }|j%                  |      j'                         d   }|||dk(  <   |S # t        $ rA t	        j
                  d       t        j                  |j                         d      d   }Y Ow xY w# t(        $ r t	        j
                  d
d       t        j*                  |j,                  t         j                  	      }	|j                         }
t/        |       D ]5  }t        j0                  |
|k(        d   dz  ddd   |	||   ||   ||   z    7 |	||dk(  <   Y |S w xY w)a  
    Find vertex face indices from the faces array of vertices

    Parameters
    -----------
    vertex_count : int
      The number of vertices faces refer to
    faces : (n, 3) int
      List of vertex indices
    faces_sparse : scipy.sparse.COO
      Sparse matrix

    Returns
    -----------
    vertex_faces : (vertex_count, ) int
      Face indices for every vertex
      Array padded with -1 in each row for all vertices with fewer
      face indices than the max number of face indices.
    )	minlengthzcasting failed, falling back!T)return_countsr   r   Nr   r   zJvertex_faces falling back to slow loop! mesh probably has degenerate facesexc_infor	   )r   bincountflatten	TypeErrorr   warninguniquer6   maxr   cumsumr5   rI   r3   scipysparseidentityintr   rK   BaseExceptionrH   sizerangewhere)vertex_countr7   faces_sparsecountsstartspackpaddedrc   sorted_facessortflatvs               r   vertex_face_indicesrs      s   ,CU]]_E v;,&&&99;%%% YYq"))F+CR01F99VZZ\"VAtG_4DD1199"((CCF#<<((U3(?#''199;A>
 +v{ MK  C345==?$?B	C0  #3	

 xx

"((3}}|$A79xx	7J17MQR7RTXVXTX6YDVAY23 % #v{M#s&   %D- AE: -AE76E7:B*H('H(c                       fd} fd}	  |       }t        j                  |      }|S # t         $ r! t        j                  dd        |       }Y @w xY w)a  
    Find vertex normals from the mean of the faces that contain
    that vertex.

    Parameters
    -----------
    vertex_count : int
      The number of vertices faces refer to
    faces : (n, 3) int
      List of vertex indices
    face_normals : (n, 3) float
      Normal vector for each face

    Returns
    -----------
    vertex_normals : (vertex_count, 3) float
      Normals for every vertex
      Vertices unreferenced by faces will be zero.
    c                  L    t              } n} | j                        }|S N)index_sparser   )r.   summedface_normalsr7   rb   ri   s     r   summed_sparsez*mean_vertex_normals.<locals>.summed_sparse/  s.     >!,6FFL)r   c                  x    t        j                  df      } t              D ]  \  }}| |xx   |z  cc<    | S Nr	   )r   rH   zip)rx   facer   ry   r7   ri   s      r   summed_loopz(mean_vertex_normals.<locals>.summed_loop:  s@     <+,|4LD&4LF"L 5r   *unable to use sparse matrix, falling back!TrX   )re   r   r]   r   unitize)	ri   r7   ry   rb   kwargsrz   r   rx   vertex_normalss	   ````     r   mean_vertex_normalsr     sV    *	 \\&)N  @4Ps   3 'AAc                 2     fd} fd}dz  j                  d      dkD  }|   |   |   |s	 t        j                   |             S t        j                   |             S # t        $ r t	        j
                  dd	       Y <w xY w)
aV  
    Compute vertex normals from the faces that contain that vertex.
    The contribution of a face's normal to a vertex normal is the
    ratio of the corner-angle in which the vertex is, with respect
    to the sum of all corner-angles surrounding the vertex.

    Grit Thuerrner & Charles A. Wuethrich (1998)
    Computing Vertex Normals from Polygonal Facets,
    Journal of Graphics Tools, 3:1, 43-46

    Parameters
    -----------
    vertex_count : int
      The number of vertices faces refer to
    faces : (n, 3) int
      List of vertex indices
    face_normals : (n, 3) float
      Normal vector for each face
    face_angles : (n, 3) float
      Angles at each vertex in the face

    Returns
    -----------
    vertex_normals : (vertex_count, 3) float
      Normals for every vertex
      Vertices unreferenced by faces will be zero.
    c                  ^    t        j                               } | j                        S )N)data)rw   ravelr   )r.   face_anglesry   r7   ri   s    r   rz   z.weighted_vertex_normals.<locals>.summed_sparsem  s+    
 lE8I8I8KLzz,''r   c                  &   t        j                  dft         j                        } t        j                        D ]Q  }t        j                  |k(        \  }}||f   }t        j
                  ||j                         z  |         | |<   S | S r|   )r   rH   r   r5   rh   r   sum)	rx   
vertex_idx	face_idxsinface_idxssurrounding_anglesr   ry   r7   ri   s	        r   r   z,weighted_vertex_normals.<locals>.summed_loopu  s    <+RZZ8))L1J &(XXez.A%B"I{!,Y-C!D!#"%7%;%;%==|I?V"F: 2 r   r1   r   )axisg      ?r   TrX   )r   r   r   re   r   r]   )ri   r7   ry   r   use_looprz   r   face_oks   ````    r   weighted_vertex_normalsr   N  s    >( Q###+c1G'NE(Lg&K	U<<00 <<&&  	UKKDtT	Us   A3 3 BBc                 T   t        j                  |      }t        |       } |j                  d      }t        j                  t        j
                  t        |            j                  d      d|j                  d   f      j                  d      }| t        |      f}|%t        j                  t        |      t              }n"t        |      t        |      k7  rt        d      ||j                  |      }t        j                  j                  |||ff||j                        S )a  
    Return a sparse matrix for which vertices are contained in which faces.
    A data vector can be passed which is then used instead of booleans

    Parameters
    ------------
    columns : int
      Number of columns, usually number of vertices
    indices : (m, d) int
      Usually mesh.faces

    Returns
    ---------
    sparse: scipy.sparse.coo_matrix of shape (columns, len(faces))
            dtype is boolean

    Examples
     ----------
    In [1]: sparse = faces_sparse(len(mesh.vertices), mesh.faces)

    In [2]: sparse.shape
    Out[2]: (12, 20)

    In [3]: mesh.faces.shape
    Out[3]: (20, 3)

    In [4]: mesh.vertices.shape
    Out[4]: (12, 3)

    In [5]: dense = sparse.toarray().astype(int)

    In [6]: dense
    Out[6]:
    array([[1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
           [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
           [0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0],
           [0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
           [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1],
           [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0],
           [0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0],
           [0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1],
           [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1]])

    In [7]: dense.sum(axis=0)
    Out[7]: array([3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3])
    r   r   r   r   zdata incorrect length)r   r   )r   r2   rd   r"   r4   r5   r6   r   onesboolr   rI   ra   rb   
coo_matrixr   )columnsindicesr   r   rowcolr   s          r   rw   rw     s    d mmG$G'lG //"
C
''
		#g,''01gmmA6F2Ggbk  c'l#E|wws3xt,	Tc#h	011{{5! <<""D3*#5U$**"UUr   )Frv   )NN)numpyr    r   	constantsr   typedr   scipy.sparsera   re   Er   ExceptionWrapperr   r
   r;   rD   r3   r   rT   rs   r   r   rw    r   r   <module>r      s       +.2j4@ $&88T A>d A>g A>H=@1j >CB'JEVU  + (J''*E	+s   A A7A22A7