a
    d$                     @   s   d dl Z d dl mZ d dlmZmZ ddlmZmZ g dZe je je jddd	Z	d
d Z
e je je jdddZe je je jdddZdeeeedddZeedddZdS )    N)Tensor)KORNIA_CHECK_IS_TENSORcheck_is_tensor   )convert_points_from_homogeneousconvert_points_to_homogeneous)compose_transformationsrelative_transformationinverse_transformationtransform_pointspoint_line_distancesquared_norm)trans_01trans_12returnc           	      C   s  t | stdt|  t |s8tdt| |  dv rV| jdd dksftd| j| dv r|jdd dkstd|j|  | kstd	|   d
|  | dddddf }|dddddf }| dddddf }|dddddf }t ||}t ||| }t 	| }|dddddf  |7  < |dddddf  |7  < |ddddf  d7  < |S )az  Function that composes two homogeneous transformations.

    .. math::
        T_0^{2} = \begin{bmatrix} R_0^1 R_1^{2} & R_0^{1} t_1^{2} + t_0^{1} \\
        \mathbf{0} & 1\end{bmatrix}

    Args:
        trans_01: tensor with the homogeneous transformation from
          a reference frame 1 respect to a frame 0. The tensor has must have a
          shape of :math:`(N, 4, 4)` or :math:`(4, 4)`.
        trans_12: tensor with the homogeneous transformation from
          a reference frame 2 respect to a frame 1. The tensor has must have a
          shape of :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Returns:
        the transformation between the two frames with shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Example::
        >>> trans_01 = torch.eye(4)  # 4x4
        >>> trans_12 = torch.eye(4)  # 4x4
        >>> trans_02 = compose_transformations(trans_01, trans_12)  # 4x4
    /Input trans_01 type is not a torch.Tensor. Got z/Input trans_12 type is not a torch.Tensor. Got       N   r   z:Input trans_01 must be a of the shape Nx4x4 or 4x4. Got {}z:Input trans_12 must be a of the shape Nx4x4 or 4x4. Got {}%Input number of dims must match. Got  and .r   r         ?)
torch	is_tensor	TypeErrortypedimshape
ValueErrorformatmatmul
zeros_like)	r   r   Zrmat_01rmat_12Ztvec_01tvec_12Zrmat_02Ztvec_02trans_02 r)   _/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/geometry/linalg.pyr      s*    


r   c                 C   s   t | stdt|  |  dv r:| jdd dksJtd| j | dddd	df }| ddddd
f }t |dd}t | |}t 	| }|dddd	df  |7  < |dddddf  |7  < |ddddf  d7  < |S )a  Function that inverts a 4x4 homogeneous transformation
    :math:`T_1^{2} = \begin{bmatrix} R_1 & t_1 \\ \mathbf{0} & 1 \end{bmatrix}`

    The inverse transformation is computed as follows:

    .. math::

        T_2^{1} = (T_1^{2})^{-1} = \begin{bmatrix} R_1^T & -R_1^T t_1 \\
        \mathbf{0} & 1\end{bmatrix}

    Args:
        trans_12: transformation tensor of shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Returns:
        tensor with inverted transformations with shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Example:
        >>> trans_12 = torch.rand(1, 4, 4)  # Nx4x4
        >>> trans_21 = inverse_transformation(trans_12)  # Nx4x4
    z&Input type is not a torch.Tensor. Got r   r   Nr   z'Input size must be a Nx4x4 or 4x4. Got .r   r   r   r   r   )
r   r   r   r   r    r!   r"   Z	transposer$   r%   )r   r&   r'   Zrmat_21Ztvec_21Ztrans_21r)   r)   r*   r
   J   s    

r
   )r   r(   r   c                 C   s   t | stdt|  t |s8tdt| |  dv rV| jdd dksftd| j| dv r|jdd dkstd|j|  | kstd|   d	|  t| }t	||}|S )
a  Function that computes the relative homogeneous transformation from a
    reference transformation :math:`T_1^{0} = \begin{bmatrix} R_1 & t_1 \\
    \mathbf{0} & 1 \end{bmatrix}` to destination :math:`T_2^{0} =
    \begin{bmatrix} R_2 & t_2 \\ \mathbf{0} & 1 \end{bmatrix}`.

    The relative transformation is computed as follows:

    .. math::

        T_1^{2} = (T_0^{1})^{-1} \cdot T_0^{2}

    Args:
        trans_01: reference transformation tensor of shape :math:`(N, 4, 4)` or :math:`(4, 4)`.
        trans_02: destination transformation tensor of shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Returns:
        the relative transformation between the transformations with shape :math:`(N, 4, 4)` or :math:`(4, 4)`.

    Example::
        >>> trans_01 = torch.eye(4)  # 4x4
        >>> trans_02 = torch.eye(4)  # 4x4
        >>> trans_12 = relative_transformation(trans_01, trans_02)  # 4x4
    r   z/Input trans_02 type is not a torch.Tensor. Got r   r   Nr   z1Input must be a of the shape Nx4x4 or 4x4. Got {}r   r   )
r   r   r   r   r    r!   r"   r#   r
   r   )r   r(   Ztrans_10r   r)   r)   r*   r	   s   s    


r	   )r   points_1r   c                 C   s2  t |  t | | jd |jd ksJ| jd dkrJtd| j d|j | jd |jd d ksvtd|  d| t|j}|d|jd |jd }| d| jd | jd } tj| |jd | jd  dd} t|}t|| 	dd	d}tj
|dd
}t|}|jd |d< |jd |d< ||}|S )a4  Function that applies transformations to a set of points.

    Args:
        trans_01 (torch.Tensor): tensor for transformations of shape
          :math:`(B, D+1, D+1)`.
        points_1 (torch.Tensor): tensor of points of shape :math:`(B, N, D)`.
    Returns:
        torch.Tensor: tensor of N-dimensional points.

    Shape:
        - Output: :math:`(B, N, D)`

    Examples:

        >>> points_1 = torch.rand(2, 4, 3)  # BxNx3
        >>> trans_01 = torch.eye(4).view(1, 4, 4)  # Bx4x4
        >>> points_0 = transform_points(trans_01, points_1)  # BxNx3
    r   r   z<Input batch size must be the same for both tensors or 1.Got r   r   z0Last input dimensions must differ by one unitGotr   )Zrepeatsr    r   r    )r   r!   r"   listZreshaper   Zrepeat_interleaver   ZbmmZpermuteZsqueezer   )r   r+   Z	shape_inpZ
points_1_hZ
points_0_hZpoints_0r)   r)   r*   r      s(    "
 
r   &.>)pointlineepsr   c                 C   s   t |  t | | jd dvr.td| j |jd dksLtd|j |d | d  |d | d   |d   }|d	d
df jdd}|||  S )a]  Return the distance from points to lines.

    Args:
       point: (possibly homogeneous) points :math:`(*, N, 2 or 3)`.
       line: lines coefficients :math:`(a, b, c)` with shape :math:`(*, N, 3)`, where :math:`ax + by + c = 0`.
       eps: Small constant for safe sqrt.

    Returns:
        the computed distance with shape :math:`(*, N)`.
    r   r   z&pts must be a (*, 2 or 3) tensor. Got r   z#lines must be a (*, 3) tensor. Got ).r   ).r   ).r   .Nr   r,   )r   r!   r"   absZnorm)r/   r0   r1   	numeratordenominatorr)   r)   r*   r      s    ,r   )xr   c                 C   s   |  ddS )z$Return the squared norm of a vector.r   r   )powsum)r5   r)   r)   r*   r      s    r   )r.   )r   r   Zkornia.testingr   r   Zconversionsr   r   __all__r   r
   r	   r   floatr   r   r)   r)   r)   r*   <module>   s   
8)'0