
    Ti9                         d dl ZddlmZ ddlmZ ddlmZ 	 d dl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 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dS )    N   )util)log)NDArray)
exceptionsc                     t          |g d          }| 8t          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      J/DATA/AppData/hermes/venv/lib/python3.11/site-packages/trimesh/geometry.pyplane_transformr      sY    " fiii00IF9bi.B.BCCBQBGG	"1"a%    Fc                    t          j        | t           j                  } t          j        |t           j                  }| j        dk    s|j        dk    rt	          d          t           j                            |                     d                    d         }t           j                            |                    d                    d         }t           j                            |          dk     r|dddfxx         dz  cc<   t           j                            |          dk     r|dddfxx         dz  cc<   t          j	        d	          }|
                    |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
   '   s   , 	"*%%%A
"*%%%Aw$!'T//0111 
qyy))	*	*1	-B	qyy))	*	*1	-B	y}}R1
111b5			T				y}}R1
111b5			T			 VAYYFVVBD\\F2A2rr6N  fRUBqE""	"'#tS1122;;RUNEu}Mr   c                 *   t          j        | t           j                  } | ddg df                             d          }|rPt          j        t          j        t          |                     d          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;   \   s     M%**E !!!''''(0099E !WRYs5zz22F;;=EEbII
j  Lr   c                    t          j        | t           j                  } t          |           dk    rt          j        g           S t          j        | d          r|                     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     M%rz222E
5zzQx||	uf	%	% 7j))]5/22 75666 U111a4[%1+66D74s##DVBIdOO$$FMr   Tuse_fanreturnc                 b    t                     dk    rt          j        d|          S 	 t          j         |           t           j                  dk    r& j        d         dk    r                     |          S t           j                  dk    rR j        d         dk    rAt          j         ddg df          ddg d	f         f                              |          S n# t          $ r Y nw xY wt          j        d
  D             t          j                  }t          j         fdt          j	        |dk              d         D             t          j                  }t          j         fdt          j	        |dk              d         D             t          j                  }|r+ fdt          j	        |dk              d         D             }ng }t          |          dk    r(t          |          dk    r|                    |          S t          |          dk    rt          j        |          }t          |          dk    r.t          j        |ddg df         |ddg d	f         f          }t          j        |||g                              |          S )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   c                 ,    g | ]}t          |          S  )r6   ).0is     r   
<listcomp>z%triangulate_quads.<locals>.<listcomp>   s    ...1A...r   c                      g | ]
}|         S rI   rI   rJ   rK   quadss     r   rL   z%triangulate_quads.<locals>.<listcomp>   s    BBBE!HBBBr   c                      g | ]
}|         S rI   rI   rN   s     r   rL   z%triangulate_quads.<locals>.<listcomp>   s    CCC!U1XCCCr   c                      g | ]
}|         S rI   rI   rN   s     r   rL   z%triangulate_quads.<locals>.<listcomp>   s    ===Qa===r   )r6   r   zerosr   r   astypevstackr   r3   nonzeror   triangle_fans_to_facesvstack_empty)rO   r   rE   lengthstriquadpolys   `      r   triangulate_quadsr\      s   * 5zzQx'''' e,,,u{q  U[^q%8%8<<&&&u{q  U[^q%8%89eAAAyyyL15III3FGHHOOPUVVV    h.....bh???G (BBBBbjA&>&>q&ABBB"(
S
S
SC8CCCCrz'Q,'?'?'BCCC28TTTD ===="*Wq["9"9!"<=== 
4yyA~~#d))q..zz%   
4yy1}}*400
4yy1}}y$qqq)))|,d111iii<.@ABBc4.//66u===s   AC+  A)C+ +
C87C8c                    	 t          j        |                                |           }nR# t          $ rE t	          j        d           t          j        |                                d          d         }Y nw xY wt          |          | k    sJ |                                | k     sJ t          j	        dt          j
        |          dd                   }t          j        |                                          |dddf         z   }|||z   dddf         k                        t           j                   }	 t          j                            t          |          t"          	          }|                    |                                          d         }|||dk    <   n# t(          $ r t	          j        d
d           t          j        |j        t           j        	          }	|                                }
t/          |           D ]F}t          j        |
|k              d         dz  ddd         |	||         ||         ||         z   <   G|	||dk    <   Y nw xY w|S )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   rS   r3   scipysparseidentityintr   rU   BaseExceptionrR   sizerangewhere)vertex_countr7   faces_sparsecountsstartspackpaddedrk   sorted_facessortflatvs               r   vertex_face_indicesr{      sg   ,CU]]__EEE C C C34445==??$???B	C
 v;;,&&&&99;;%%%% Yq")F++CRC011F9VZZ\\""VAAAtG_4DD1199"(CCCF#<((U3(??#''1199;;A>
 +v{ # # #3	
 	
 	
 	

 x
"(333}}|$$ 	Z 	ZA79x	7J7J17MQR7RTXTXVXTX6YDVAY2233"v{# Ms$   (+ AA:9A: A)F* *B8I%$I%c                       fd} fd}	  |            }n0# t           $ r# t          j        dd            |            }Y nw xY wt          j        |          }|S )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                  \    t                    } n} |                               }|S N)index_sparser   )r.   summedface_normalsr7   rj   rq   s     r   summed_sparsez*mean_vertex_normals.<locals>.summed_sparse/  s6     >!,66FFFL))r   c                      t          j        df          } t                    D ]\  }}| |xx         |z  cc<   | S Nr	   )r   rR   zip)r   facer   r   r7   rq   s      r   summed_loopz(mean_vertex_normals.<locals>.summed_loop:  sS     <+,,|44 	# 	#LD&4LLLF"LLLLr   *unable to use sparse matrix, falling back!Tr`   )rm   r   re   r   unitize)	rq   r7   r   rj   kwargsr   r   r   vertex_normalss	   ````     r   mean_vertex_normalsr     s    *	 	 	 	 	 	 	 	         @4PPPP
 \&))Ns   
  *AAc                 V     fd} fd}dz                       d          dk    }|         |         |         |sC	 t          j         |                      S # t          $ r t	          j        dd	           Y nw xY wt          j         |                      S )
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                  v    t                                                    } |                               S )N)data)r   ravelr   )r.   face_anglesr   r7   rq   s    r   r   z.weighted_vertex_normals.<locals>.summed_sparsem  s7    
 lE8I8I8K8KLLLzz,'''r   c                  (   t          j        dft           j                  } t          j                  D ]Z}t          j        |k              \  }}||f         }t          j        ||                                z  |                   | |<   [| S r   )r   rR   r   r5   rp   r   sum)	r   
vertex_idx	face_idxsinface_idxssurrounding_anglesr   r   r7   rq   s	        r   r   z,weighted_vertex_normals.<locals>.summed_loopu  s    <+RZ88)L11 	 	J &(Xez.A%B%B"I{!,Y-C!D!#"%7%;%;%=%==|I?V" "F: r   r1   r   )axisg      ?r   Tr`   )r   r   r   rm   r   re   )rq   r7   r   r   use_loopr   r   face_oks   ````    r   weighted_vertex_normalsr   N  s   >( ( ( ( ( ( ( (        Q###++c1G'NE(Lg&K U	U<000 	U 	U 	UKDtTTTTTT	U <&&&s   A) ) BBc                    t          j        |          }t          |           } |                    d          }t          j        t          j        t          |                                        d          d|j        d         f                              d          }| t          |          f}|)t          j        t          |          t                    }n/t          |          t          |          k    rt          d          ||                    |          }t          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   Nr   zdata incorrect length)r   r   )r   r2   rl   r"   r4   r5   r6   r   onesboolr   rS   ri   rj   
coo_matrixr   )columnsindicesr   r   rowcolr   s          r   r   r     s   d mG$$G'llG //"

C
'
	#g,,''001gmA6F2G gbkk  c'll#E|ws3xxt,,,	Tc#hh		0111{{5!! <""D3*#5U$*"UUUr   )Fr~   )NN)numpyr    r   	constantsr   typedr   scipy.sparseri   rm   Er   ExceptionWrapperr   r
   r;   rD   r3   r   r\   r{   r   r   r   rI   r   r   <module>r      s                        + + + + (J'**EEEEEE	+  .2 2 2 2j   4  @ $&8T A> A>d A>g A> A> A> A>H= = =@1 1 1 1j >CB' B' B' B'JEV EV EV EV EV EVs    A=A