o
    i                     @   s  d dl mZmZ d dlZd dlmZ d dlm  mZ d#ddZ	G dd dej
Z		d$d
ejdededejfddZd$dedejdedejfddZ			d%dedededejdejdejfddZ				d&dejdeeeef df deedf ded edejfd!d"ZdS )'    )TupleUnionNnorm_expexpp1c                 C   s  |  dddd}|du rdn|}|ddddddd| f }|dkr3|dddddddf n|dddddd| df }|dkr_|jddd	jd
d}|| }|t| }	n:|dkrm||jddd	 }	n,|dkrwt|}	n"|dkrt|}	n|dkrt|}	n|dkr|}	nt	d| |dkrd|  }
|	|
fS |dkr| }
|	|
fS |dkrt|}
|	|
fS |dkr|}
|	|
fS t	d| )aq  
    Process network output to extract GS params and density values.
    Density could be view-dependent as SH coefficient


    Args:
        out: Network output tensor (B, C, H, W)
        activation: Activation type for 3D points
        conf_activation: Activation type for confidence values

    Returns:
        Tuple of (3D points tensor, confidence tensor)
    r            Nr   T)dimkeepdimg:0yE>)minnormexprelusigmoidlinearzUnknown activation: r   Zexpp0zUnknown conf_activation: )
permuter   clamptorchexpm1r   Fr   r   
ValueError)out
activationconf_activationZconf_dimfmapxyzconfdZ
xyz_normedZpts3dZconf_out r   E/data/cameron/da3_repo/src/depth_anything_3/model/utils/head_utils.pyactivate_head_gs   s@   "F

r!   c                       sZ   e Zd ZU dZeedf ed< deedf ddf fddZdej	dej	fd	d
Z
  ZS )PermutezHnn.Module wrapper around Tensor.permute for cleaner nn.Sequential usage..dimsreturnNc                    s   t    || _d S N)super__init__r#   )selfr#   	__class__r   r    r'   X   s   

zPermute.__init__xc                 C   s   |j | j S r%   )r   r#   )r(   r+   r   r   r    forward\   s   zPermute.forward)__name__
__module____qualname____doc__r   int__annotations__r'   r   Tensorr,   __classcell__r   r   r)   r    r"   S   s
   
 r"   d   pos_grid	embed_dimomega_0r$   c           
      C   s   | j \}}}|dksJ | d|}t|d |dddf |d}t|d |dddf |d}tj||gdd}	|	|||S )a*  
    Convert 2D position grid (HxWx2) to sinusoidal embeddings (HxWxC)

    Args:
        pos_grid: Tensor of shape (H, W, 2) containing 2D coordinates
        embed_dim: Output channel dimension for embeddings

    Returns:
        Tensor of shape (H, W, embed_dim) with positional embeddings
    r   r	   Nr   )r8   r   r
   )shapereshapemake_sincos_pos_embedr   catview)
r6   r7   r8   HWZgrid_dimZpos_flatZemb_xZemb_yembr   r   r    position_grid_to_embed`   s   rB   posc                 C   s   | d dksJ t j| d t j|jd}|| d  }d||  }|d}t d||}t |}t |}t j||gdd	}|	 S )
a"  
    This function generates a 1D positional embedding from a given grid using sine and cosine functions. # noqa

    Args:
    - embed_dim: The embedding dimension.
    - pos: The position to generate the embedding from.

    Returns:
    - emb: The generated 1D positional embedding.
    r   r   )dtypedeviceg       @      ?r	   zm,d->mdr   r9   )
r   arangefloat32rE   r;   einsumsincosr=   float)r7   rC   r8   omegar   emb_sinemb_cosrA   r   r   r    r<   {   s   


r<   widthheightaspect_ratiorD   rE   c                 C   s   |du rt | t | }|d d d }|| }d| }| | d  |  }|| d  |  }	| |d  | }
||d  | }tj||	| ||d}tj|
||||d}tj||dd\}}tj||fd	d
}|S )a  
    Create a normalized UV grid of shape (width, height, 2).

    The grid spans horizontally and vertically according to an aspect ratio,
    ensuring the top-left corner is at (-x_span, -y_span) and the bottom-right
    corner is at (x_span, y_span), normalized by the diagonal of the plane.

    Args:
        width (int): Number of points horizontally.
        height (int): Number of points vertically.
        aspect_ratio (float, optional): Width-to-height ratio. Defaults to width/height.
        dtype (torch.dtype, optional): Data type of the resulting tensor.
        device (torch.device, optional): Device on which the tensor is created.

    Returns:
        torch.Tensor: A (width, height, 2) tensor of UV coordinates.
    Nr   rF   g      ?r   )stepsrD   rE   xy)indexingr	   r9   )rL   r   linspacemeshgridstack)rP   rQ   rR   rD   rE   Zdiag_factorZspan_xZspan_yZleft_xZright_xZtop_yZbottom_yx_coordsy_coordsuuvvZuv_gridr   r   r    create_uv_grid   s   r]   bilinearTr+   sizescale_factormodealign_cornersc           	         s   du r|dusJ dt | jd | t | jd | fd}d d  | jd  | jd  }||krVtj| || d dd} fd	d
|D }tj|dd S tjj|  dS )zi
    Safe interpolation implementation to avoid INT_MAX overflow in torch.nn.functional.interpolate.
    Nz-Either size or scale_factor must be provided.r	   i   `r   r   )chunksr
   c                    s    g | ]}t jj| d qS )r_   ra   rb   )nn
functionalinterpolate).0crb   ra   r_   r   r    
<listcomp>   s    z&custom_interpolate.<locals>.<listcomp>r9   re   )	r1   r:   r   chunkr=   
contiguousrf   rg   rh   )	r+   r_   r`   ra   rb   ZINT_MAXtotalrd   outsr   rk   r    custom_interpolate   s   
$$rq   )r   r   N)r5   )NNN)NNr^   T)typingr   r   r   torch.nnrf   Ztorch.nn.functionalrg   r   r!   Moduler"   r3   r1   rL   rB   r<   rD   rE   r]   strboolrq   r   r   r   r    <module>   sd   
:
  
7
