o
    pi                  	   @   s  d dl Z d dlmZ d dlmZmZmZ d dlZd dl	Z	d dl
m  mZ d dl	mZ ddlmZmZ ddlmZ ddlmZ d	d
lmZ de	jdede	jfddZd?de	jdedede	jfddZdd Zd@ddZdedefddZdd Zdd Z d e	jfd!d"Z!d#e	jd$eeeef fd%d&Z"G d'd( d(ej#Z$eG d)d* d*Z%G d+d, d,ej#Z&G d-d. d.ej#Z'G d/d0 d0ej#Z(eG d1d2 d2eZ)G d3d4 d4ej#Z*eG d5d6 d6eZ+G d7d8 d8eeZ,G d9d: d:ej#Z-G d;d< d<eeZ.G d=d> d>eeZ/dS )A    N)	dataclass)DictOptionalTuple)nn   )ConfigMixinregister_to_config)
ModelMixin)
BaseOutput   )create_pan_cameraspmf	n_samplesreturnc                 C   st   | j ^ }}}|dksJ tj| d|dd}t|tj|j d ||jd}|jg ||dR  d|d S )a>  
    Sample from the given discrete probability distribution with replacement.

    The i-th bin is assumed to have mass pmf[i].

    Args:
        pmf: [batch_size, *shape, n_samples, 1] where (pmf.sum(dim=-2) == 1).all()
        n_samples: number of samples

    Return:
        indices sampled with replacement
    r   dimr   device)shapetorchcumsumviewsearchsortedrandr   clamp)r   r   r   support_sizelast_dimcdfinds r!   a/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/diffusers/pipelines/shap_e/renderer.py
sample_pmf   s
    $r#      xmin_degmax_degc                 C   s   ||kr| S dt j||| j| jd }| j^ }}| dd||ddd jg |dR  }|jd |||  ks<J t j||tj	d  gdd
 }t j| |gddS )zz
    Concatenate x and its positional encodings, following NeRF.

    Reference: https://arxiv.org/pdf/2210.04628.pdf
    g       @)dtyper   r   r   )axisr   )r   aranger(   r   r   reshaper   catmathpisin)r%   r&   r'   scalesr   r   xbembr!   r!   r"   posenc_nerf5   s   , r3   c                 C   s   t | dddS )Nr   r$   r&   r'   )r3   positionr!   r!   r"   encode_positionF   s   r7   c                 C   s*   |d u rt t| dddS t|dddS )Nr      r4   )r   
zeros_liker3   )r6   	directionr!   r!   r"   encode_directionJ   s   r;   c                 C   s   |  ddS )N.__)replacer%   r!   r!   r"   _sanitize_nameQ   s   r@   c              
   C   s   |  |\}}}|| }tj|dd}t|ddddf  }dt|  }	ttjt|dddddf |dddddf  gdd}
|	|
 }tj|| dd}|||fS )a  
    Function integrating the model output.

    Args:
        volume_range: Specifies the integral range [t0, t1]
        ts: timesteps
        density: torch.Tensor [batch_size, *shape, n_samples, 1]
        channels: torch.Tensor [batch_size, *shape, n_samples, n_channels]
    returns:
        channels: integrated rgb output weights: torch.Tensor [batch_size, *shape, n_samples, 1] (density
        *transmittance)[i] weight for each rgb output at [..., i, :]. transmittance: transmittance of this volume
    )
    r   .r   N      ?r   )	partitionr   r   expr,   r9   sum)volume_rangetsdensitychannels_dtddensitymasstransmittancealphasTsweightsr!   r!   r"   integrate_samplesU   s   D
rR   c                 C   s   t j|d | jjd}|| }t j||dd| }t j||d dd| }t j|||gdd}| |d  | j| j  | j S )Nr   r   trunc)rounding_mode   r   r   )r   r*   bbox_minr   divstackfloatbbox_max)volume	grid_sizeindiceszsysxscombinedr!   r!   r"   volume_query_pointsw   s   "rb   uc                 C   s"   t | dk| d | d d d S )Ng?ܵ?gףp=
)@g)\(?gzG?g333333@r   where)rc   r!   r!   r"   _convert_srgb_to_linear   s   "rf   flat_cube_indicesr\   c                 C   s  |d d |d  |d  }|}|d |d d  |d  }|| }t j| d d df |d  |d  | d d df |d   | d d df  | d d df |d  |d  | d d df d |d   | d d df  | d d df |d  |d  | d d df |d   | d d df  d | d d df |d  |d  | d d df d |d   | d d df  d || d d df |d d  |d   | d d df |d   | d d df  || d d df d |d d  |d   | d d df |d   | d d df  || d d df |d d  |d   | d d df |d   | d d df  d || d d df d |d d  |d   | d d df |d   | d d df  d || d d df |d  |d d   | d d df |d d   | d d df  || d d df d |d  |d d   | d d df |d d   | d d df  || d d df |d  |d d   | d d df d |d d   | d d df  || d d df d |d  |d d   | d d df d |d d   | d d df  gddS )Nr   r   rU   r   r   )r   rX   )rg   r\   num_xsy_offsetnum_ysz_offsetr!   r!   r"   _create_flat_edge_indices   s   "&"&"&"&Erl   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )VoidNeRFModelz`
    Implements the default empty space model where all queries are rendered as background.
         o@c                    s>   t    ttt|jtj	d| }| 
d| d S )Nr(   
background)super__init__r   	Parameterr   
from_numpynparraytofloat32register_buffer)selfrp   channel_scale	__class__r!   r"   rr      s   
$zVoidNeRFModel.__init__c                 C   sl   | j d  |j}|jd d }dgt|d  }|jd }t|j|jd g||R  g ||}|S )Nr   r   r   )rp   rw   r   r   lenr   broadcast_tor   )rz   r6   rp   r   ones
n_channelsr!   r!   r"   forward   s   
,zVoidNeRFModel.forward)rn   )__name__
__module____qualname____doc__rr   r   __classcell__r!   r!   r|   r"   rm      s    rm   c                   @   s<   e Zd ZU ejed< ejed< ejed< dd Zdd ZdS )	VolumeRanget0t1intersectedc                 C   s,   | j j| jj  kr| jjksJ  J d S N)r   r   r   r   )rz   r!   r!   r"   __post_init__   s   ,zVolumeRange.__post_init__c                 C   s   |dddddf |dddddf  d }t j| jddddf |gdd}t j|| jddddf gdd}|| }|j|j  krR|j  krR|jksUJ  J |||fS )ar  
        Partitions t0 and t1 into n_samples intervals.

        Args:
            ts: [batch_size, *shape, n_samples, 1]

        Return:

            lower: [batch_size, *shape, n_samples, 1] upper: [batch_size, *shape, n_samples, 1] delta: [batch_size,
            *shape, n_samples, 1]

        where
            ts \in [lower, upper] deltas = upper - lower
        .r   Nr         ?rA   r   )r   r,   r   r   r   )rz   rG   midslowerupperdeltar!   r!   r"   rC      s   0"".
zVolumeRange.partitionN)r   r   r   r   Tensor__annotations__r   rC   r!   r!   r!   r"   r      s   
 


r   c                       sX   e Zd ZdZddddedef fddZ			
ddejdejdeej fddZ	  Z
S )BoundingBoxVolumezH
    Axis-aligned bounding box defined by the two opposite corners.
            MbP?)min_distmin_t_ranger   r   c                   sn   t    || _|| _t|| _t|| _t| j| jg| _	| j	j
dks)J |dks/J |dks5J dS )z
        Args:
            bbox_min: the left/bottommost corner of the bounding box
            bbox_max: the other corner of the bounding box
            min_dist: all rays should start at least this distance away from the origin.
        rU   r   r   N)rq   rr   r   r   r   tensorrV   rZ   rX   bboxr   )rz   rV   rZ   r   r   r|   r!   r"   rr     s   
zBoundingBoxVolume.__init__Nư>originr:   t0_lowerc                 C   sH  |j ^}}}dgt| }| jjdg|ddR  |j}	ddd}
|
|	|ddddf  |ddddf |d	}|jd
djjdddj	| j
}|jd
djjdddj}|j |j   krm|g|dR kspJ  J |dur|j |j ks|J t||}|| j |k }t||t|}t||t|}t|||dS )a  
        Args:
            origin: [batch_size, *shape, 3]
            direction: [batch_size, *shape, 3]
            t0_lower: Optional [batch_size, *shape, 1] lower bound of t0 when intersecting this volume.
            params: Optional meta parameters in case Volume is parametric
            epsilon: to stabilize calculations

        Return:
            A tuple of (t0, t1, intersected) where each has a shape [batch_size, *shape, 1]. If a ray intersects with
            the volume, `o + td` is in the volume for all t in [t0, t1]. If the volume is bounded, t1 is guaranteed to
            be on the boundary of the volume.
        r   rU   r   r   c                 S   s   | t |dk || ||  S Nr   rd   )abepsilonr!   r!   r"   _safe_divideE  s   z1BoundingBoxVolume.intersect.<locals>._safe_divide.N)r   rA   r   r   Tr   keepdim)r   r   r   )r   )r   r~   r   r   rw   r   minvaluesmaxr   r   r   maximumr   re   r9   	ones_liker   )rz   r   r:   r   r   
batch_sizer   rJ   r   r   r   rG   r   r   r   r!   r!   r"   	intersect,  s   $
.",zBoundingBoxVolume.intersect)Nr   )r   r   r   r   rY   rr   r   r   r   r   r   r!   r!   r|   r"   r     s$    	r   c                   @   sH   e Zd ZdZddefddZ	ddejdejd	ed
e	dejf
ddZ
dS )StratifiedRaySamplerz_
    Instead of fixed intervals, a sample is drawn uniformly at random from each interval.
    linear
depth_modec                 C   s   || _ | j dv s
J dS )z
        :param depth_mode: linear samples ts linearly in depth. harmonic ensures
            closer points are sampled more densely.
        )r   	geometricharmonicN)r   )rz   r   r!   r!   r"   rr   f  s   zStratifiedRaySampler.__init__r   r   r   r   r   r   c                 C   sF  dgt |jd  }tdd|jg ||R  |j|j}| jdkr1|d|  ||  }n7| jdkrM|	|
 d|  |	|
 |   }n| jdkrhdd|	| d|  d|	| |   }d|ddd	f |dd	d
f   }tj||gd
d}tj||gd
d}	td t|}
|	||	 |
  }|d
S )  
        Args:
            t0: start time has shape [batch_size, *shape, 1]
            t1: finish time has shape [batch_size, *shape, 1]
            n_samples: number of ts to sample
        Return:
            sampled ts of shape [batch_size, *shape, n_samples, 1]
        r   r   r   rB   r   r   r   .Nr   r   )r~   r   r   linspacer   rw   r(   r   r   r   logrD   r,   manual_seed	rand_like	unsqueeze)rz   r   r   r   r   r   rG   r   r   r   t_randr!   r!   r"   samplen  s   .

.
,$


zStratifiedRaySampler.sampleN)r   )r   )r   r   r   r   strrr   r   r   intrY   r   r!   r!   r!   r"   r   a  s    r   c                   @   s`   e Zd ZdZ		ddedejdejdedef
d	d
Z	e
 dejdejdedejfddZdS )ImportanceRaySamplerzp
    Given the initial estimate of densities, this samples more from regions/bins expected to have objects.
    Fh㈵>rF   rG   rQ   	blur_poolalphac                 C   s2   || _ |  | _|  | _|| _|| _dS )am  
        Args:
            volume_range: the range in which a ray intersects the given volume.
            ts: earlier samples from the coarse rendering step
            weights: discretized version of density * transmittance
            blur_pool: if true, use 2-tap max + 2-tap blur filter from mip-NeRF.
            alpha: small value to add to weights.
        N)rF   clonedetachrG   rQ   r   r   )rz   rF   rG   rQ   r   r   r!   r!   r"   rr     s
   
zImportanceRaySampler.__init__r   r   r   r   c                 C   s|  | j | j\}}}| jj^}}}	}| j}
| jretj|
dddddf |
|
dddddf gdd}t|dddddf |dddddf }d|dddddf |dddddf   }
|
| j	 }
|
|
j
ddd	 }t||}|j|g||dR ksJ |d
k r||	k  sJ tj|j|jd}t|d|}t|d|}||| |  }tj|ddj}|S )r   .Nr   r   rA   r   r   Tr   r   r   )rF   rC   rG   r   rQ   r   r   r,   r   r   rE   r#   allr   r   gathersortr   )rz   r   r   r   r   r   rJ   r   r   n_coarse_samplesrQ   paddedmaxesr   r    r   lower_upper_rG   r!   r!   r"   r     s$   
800

zImportanceRaySampler.sampleN)Fr   )r   r   r   r   r   r   r   boolrY   rr   no_gradr   r   r!   r!   r!   r"   r     s"    	
&r   c                   @   s8   e Zd ZU dZejed< ejed< eeejf ed< dS )MeshDecoderOutputax  
    A 3D triangle mesh with optional data at the vertices and faces.

    Args:
        verts (`torch.Tensor` of shape `(N, 3)`):
            array of vertext coordinates
        faces (`torch.Tensor` of shape `(N, 3)`):
            array of triangles, pointing to indices in verts.
        vertext_channels (Dict):
            vertext coordinates for each color channel
    vertsfacesvertex_channelsN)	r   r   r   r   r   r   r   r   r   r!   r!   r!   r"   r     s
   
 

r   c                       s<   e Zd ZdZ fddZdejdejdejfddZ  ZS )	MeshDecoderz\
    Construct meshes from Signed distance functions (SDFs) using marching cubes method
    c                    sL   t    tjdddtjd}tjddtjd}| d| | d| d S )N      r   ro   casesmasks)rq   rr   r   zeroslongr   ry   )rz   r   r   r|   r!   r"   rr     s
   
zMeshDecoder.__init__field	min_pointsizec               	   C   s4  t |jdksJ d|j}| j|}| j|}||}||}|j}t||}|dktj}	|	ddddddf |	ddddddf d> B }	|	ddddddf |	ddddddf d> B }	|	ddddddf |	ddddddf d> B }	tj	g |dR ||j
d	}
tj|d ||j
d	ddddf |
t|d dddddf< tj|d ||j
d	dddf |
ddt|d dddf< tj|d ||j
d	|
ddddt|d df< tj|
dd |
dd  d dd|
ddddf |
ddddf  d dd|
ddddddf |
ddddddf  d ddgdd
}tj|d d |d d |d d d|tjd	}tj|d d |dddddf |t|d d dddddf< tj|d d |ddddf |ddt|d d dddf< tj|d d |d|ddddt|d d df< |dd}t||}|	d }|| }|| }t|d||jd d|j}|dd|d }t|d}|| }tjt ||tjd	}tjt ||tjd	||< t|d|d|j}t|tj}t|tj}||dddf |dddf |dddf f }||dddf |dddf |dddf f }| |d  | | }| |d  | | }|||  dddf }|| d| |  }t||ddS )aI  
        For a signed distance field, produce a mesh using marching cubes.

        :param field: a 3D tensor of field values, where negative values correspond
                    to the outside of the shape. The dimensions correspond to the x, y, and z directions, respectively.
        :param min_point: a tensor of shape [3] containing the point corresponding
                        to (0, 0, 0) in the field.
        :param size: a tensor of shape [3] containing the per-axis distance from the
                    (0, 0, 0) field corner and the (-1, -1, -1) field corner.
        r   zinput must be a 3D scalar fieldr   Nr   r   rU      r   r(   r   r   )r   r   r   )r~   r   r   r   rw   r   r   r   uint8emptyr(   r*   ranger,   r+   r   r   rl   r   uniquer   floorceilrY   r   ) rz   r   r   r   devr   r   r\   grid_size_tensorbitmaskscorner_coordsedge_midpointscube_indicesrg   edge_indicesflat_bitmasks
local_trislocal_masksglobal_trisselected_trisused_vertex_indicesused_edge_midpointsold_index_to_new_indexr   v1v2s1s2p1p2tr   r!   r!   r"   r     st   

888 
 2"2>
&DB6

22zMeshDecoder.forward)	r   r   r   r   rr   r   r   r   r   r!   r!   r|   r"   r     s    $r   c                   @   s6   e Zd ZU ejed< ejed< ejed< ejed< dS )MLPNeRFModelOutputrH   signed_distancerI   rG   N)r   r   r   r   r   r   r!   r!   r!   r"   r   Y  s
   
 


r   c                       sZ   e Zd Ze					ddededed	ed
ef
 fddZdd ZdddddZ  Z	S )MLPNeRSTFModelr         swishr   d_hiddenn_outputn_hidden_layersact_fninsert_direction_atc                    s   t    tdd}t|djd }t|djd }|g| }	|g|	 }
|	|g }|d ur6|
|  |7  < tdd t	|
|D | _
|dkrNdd	 | _ntd
| tj| _tjjj| _tj| _d S )Nr   r   r5   r   c                 S   s   g | ]
\}}t ||qS r!   )r   Linear).0d_ind_outr!   r!   r"   
<listcomp>{  s    z+MLPNeRSTFModel.__init__.<locals>.<listcomp>r   c                 S   s
   t | S r   )Fsilur?   r!   r!   r"   <lambda>  s   
 z)MLPNeRSTFModel.__init__.<locals>.<lambda>z Unsupported activation function )rq   rr   r   eyer7   r   r;   r   
ModuleListzipmlp
activation
ValueErrortanhsdf_activation
functionalreludensity_activationsigmoidchannel_activation)rz   r   r   r  r  r  dummyd_posenc_posd_posenc_dir
mlp_widthsinput_widthsoutput_widthsr|   r!   r"   rr   b  s    
	


zMLPNeRSTFModel.__init__c                    s,   ddddddd} fdd	|  D }|S )
N)r   r   )r   rU   r   )r   r   )r   	   )r  r   )sdfdensity_coarsedensity_finestfnerf_coarse	nerf_finec                    s&   i | ]\}\}}| d ||f qS ).r!   )r  kstartendoutputr!   r"   
<dictcomp>  s   & z6MLPNeRSTFModel.map_indices_to_keys.<locals>.<dictcomp>)items)rz   r*  h_mapmapped_outputr!   r)  r"   map_indices_to_keys  s   	z"MLPNeRSTFModel.map_indices_to_keyscoarsenerf)
nerf_levelrendering_modec                C   s  t |}|}d }t| jD ]/\}	}
|	| jjkr(|}t||d}tj||gdd}|
|}|}|	t| jd k r<| 	|}q|}|d u rE|}| 
|}|dkrS|d }n|d }|dkri|dkrd|d	 }n|d
 }n|dkrq|d }| |}| |d }| |}t||||dS )N)r:   r   r   r   r0  r!  r"  r1  r$  r%  r#  r   )rH   r   rI   rG   )r7   	enumerater  configr  r;   r   r,   r~   r  r/  r  r  r  r   )rz   r6   r:   rG   r2  r3  hh_preacth_directionlessilayerh_directionh_finalr  	h_density
h_channelsrH   r   rI   r!   r!   r"   r     s<   






zMLPNeRSTFModel.forward)r   r   r   r   r   )
r   r   r   r	   r   r   rr   r/  r   r   r!   r!   r|   r"   r   a  s(    %r   c                       s@   e Zd Zdededef fddZdejdejfdd	Z  ZS )
ChannelsProjvectorsrI   d_latentc                   s>   t    t||| | _t|| _|| _|| _|| _	d S r   )
rq   rr   r   r  proj	LayerNormnormrA  r@  rI   )rz   r@  rI   rA  r|   r!   r"   rr     s   

zChannelsProj.__init__r%   r   c                 C   sV   |}| j j| j| j| j}| j jd| j| j}td||}| 	|}|| }|S )Nr   zbvd,vcd->bvc)
rB  weightr   r@  rI   rA  biasr   einsumrD  )rz   r%   x_bvdw_vcdb_vcr6  r!   r!   r"   r     s   
zChannelsProj.forward)	r   r   r   r   rr   r   r   r   r   r!   r!   r|   r"   r?    s    r?  c                       sX   e Zd ZdZedddddee deee  def fd	d
Zde	j
fddZ  ZS )ShapEParamsProjModelz
    project the latent representation of a 3D asset to obtain weights of a multi-layer perceptron (MLP).

    For more details, see the original paper:
    znerstf.mlp.0.weightznerstf.mlp.1.weightznerstf.mlp.2.weightznerstf.mlp.3.weight)r   ]   r   r   rO  rO     param_namesparam_shapesrA  rR  rS  rA  c                   sb   t    t|t|krtdti | _t||D ]\}\}}t|||d| jt	|< qd S )Nz;Must provide same number of `param_names` as `param_shapes`)r@  rI   rA  )
rq   rr   r~   r  r   
ModuleDictprojectionsr  r?  r@   )rz   rR  rS  rA  r&  r@  rI   r|   r!   r"   rr     s   
zShapEParamsProjModel.__init__r%   c           
      C   sx   i }d}t | jj| jjD ],\}}|\}}|| }|d d ||f }	| jt| |	jt|g|R  ||< |}q|S r   )r  r5  rR  rS  rU  r@   r+   r~   )
rz   r%   outr'  r&  r   r@  rJ   r(  rH  r!   r!   r"   r     s   (zShapEParamsProjModel.forward)r   r   r   r   r	   r   r   r   rr   r   r   r   r   r!   r!   r|   r"   rK    s    
	rK  c                       s   e Zd Zeddddddddd	d
	dee deee  dededededededee f fddZe	
 d'ddZe	
 				d(dedefdd Ze	
 			!d)d"ed#ed$efd%d&Z  ZS )*ShapERendererrL  rM  rP  r   r   r   r   r   )rn   rn   rn   )	rR  rS  rA  r   r   r  r  r  rp   rR  rS  rA  r   r   r  r  r  rp   c       	   
         s\   t    t|||d| _t|||||| _t|	dd| _tg dg dd| _	t
 | _d S )NrQ  rn   )rp   r{   )rB   rB   rB   )      rX  rX  )rZ   rV   )rq   rr   rK  params_projr   r  rm   voidr   r[   r   mesh_decoder)
rz   rR  rS  rA  r   r   r  r  r  rp   r|   r!   r"   rr     s   
zShapERenderer.__init__NFc                 C   s  |ddddf |ddddf }}| j j||dd}||j|j|}	|	|j}	|dur?tjtj	|	|j
gddddj}	|jj^}
}}|	j^}}}t|d|
g|d}|d|	|  }|| jj}|| jj}|rw|nd}| j|||	|du rd	nd
d}t||j
|j|j\}}}t|j|t|}t|j|t|}||| |  }t||j
|d}|||fS )a|  
        Perform volumetric rendering over a partition of possible t's in the union of rendering volumes (written below
        with some abuse of notations)

            C(r) := sum(
                transmittance(t[i]) * integrate(
                    lambda t: density(t) * channels(t) * transmittance(t), [t[i], t[i + 1]],
                ) for i in range(len(parts))
            ) + transmittance(t[-1]) * void_model(t[-1]).channels

        where

        1) transmittance(s) := exp(-integrate(density, [t[0], s])) calculates the probability of light passing through
        the volume specified by [t[0], s]. (transmittance of 1 means light can pass freely) 2) density and channels are
        obtained by evaluating the appropriate part.model at time t. 3) [t[i], t[i + 1]] is defined as the range of t
        where the ray intersects (parts[i].volume \ union(part.volume for part in parts[:i])) at the surface of the
        shell (if bounded). If the ray does not intersect, the integral over this segment is evaluated as 0 and
        transmittance(t[i + 1]) := transmittance(t[i]). 4) The last term is integration to infinity (e.g. [t[-1],
        math.inf]) that is evaluated by the void_model (i.e. we consider this space to be empty).

        Args:
            rays: [batch_size x ... x 2 x 3] origin and direction. sampler: disjoint volume integrals. n_samples:
            number of ts to sample. prev_model_outputs: model outputs from the previous rendering step, including

        :return: A tuple of
            - `channels`
            - A importance samplers for additional fine-grained rendering
            - raw model output
        .r   Nr   )r   rA   r   r   r0  fine)r6   r:   rG   r2  )rG   rQ   )r[   r   r   r   r   rw   r(   r   r   r,   rG   r   r   r   r   r  rR   rH   rI   re   r   r   r9   rZ  r   )rz   rayssamplerr   prev_model_outrender_with_directionr   r:   vrangerG   r   _shape_t0_dimrJ   ts_shape_ts_dim
directions	positionsoptional_directions	model_outrI   rQ   rN   weighted_samplerr!   r!   r"   render_rays9  s6   & 

zShapERenderer.render_rays@         r   ray_batch_sizec                 C   s  |  |}| j  D ]\}}	d| | v r&|	|d|  d qt|}
|
j}|	|}|j
d | }t }g }t|D ]-}|d d || |d | f }| |||\}}}| j||||d\}}}|| qCtj|dd}|jg |
j
|
j|
jdR  d}|S )Nnerstf.r   r   )r_  r   r   )rY  r  
state_dictr,  keyscopy_squeezer   camera_raysrw   r   r   r   rk  appendr   r,   r   heightwidth)rz   latentsr   r   ro  r   n_fine_samplesprojected_paramsnameparamcamerar]  	n_batchescoarse_samplerimagesidx
rays_batchrJ   fine_samplercoarse_model_outrI   r!   r!   r"   decode_to_image  s*   

 (zShapERenderer.decode_to_imageRGBr\   query_batch_sizetexture_channelsc                    s  |  |}| j  D ]\}}d| | v r&||d|  d qt| j|}	|	d  	dddj
|| jjd}
g }td|
jd |D ]}|
d d ||| f }| j|d d ddd}||j qHtj|dd}| }t|jd	kr|jd
 dksJ d|j |jdg|gd	 R  }tjd|d |d |d |j|jd}|d ||d d dd
dd
dd
f< |}g }g }|D ]}| || jj| jj| jj }|d || qtj||jd}tdd |D  tj fdd|D dd}|j
|| jjd}g }td|jd |D ]}|d d ||| f }| j|d d ddd}||j qtj|dd}t|}| }t|jd	krT|jd
 t|ks\J d|j t ||D ]\}}|d t|j! }t"t ||#d
|_$qa|d S )Nrp  r   r   r   r\  r#  )r6   r:   rG   r2  r3  r   r   r   z9expected [meta_batch x inner_batch] SDF results, but got rU   rX  Tr   c                 s   s    | ]}t |jV  qd S r   )r~   r   r  mr!   r!   r"   	<genexpr>  s    z/ShapERenderer.decode_to_mesh.<locals>.<genexpr>c                    s(   g | ]}|j td  t|j   qS )r   )r   r   r*   r~   r  max_verticesr!   r"   r    s   ( z0ShapERenderer.decode_to_mesh.<locals>.<listcomp>zNexpected [meta_batch x inner_batch x texture_channels] field results, but got )%rY  r  rq  r,  rr  rs  rt  rb   r[   repeatrw   r(   r   r   rv  r   r   r,   rY   r~   r+   r   r   fill_r[  rV   rZ   r   r   rX   rI   rf   r  r   dictunbindr   )rz   ry  r   r\   r  r  r{  r|  r}  query_pointsquery_positionsfieldsr  query_batchri  	full_grid
raw_meshes	mesh_maskr   raw_meshtexture_query_positionstexturestexture_model_outr  texturer!   r  r"   decode_to_mesh  s~   

 


 



zShapERenderer.decode_to_mesh)NF)rl  rm  rl  rn  )rn  rm  r  )r   r   r   r	   r   r   r   rY   rr   r   r   rk  r  r  r   r!   r!   r|   r"   rW    sj    
	'N,rW  )r   r$   r   )0r-   dataclassesr   typingr   r   r   numpyru   r   torch.nn.functionalr   r  r	  configuration_utilsr   r	   modelsr
   utilsr   r~  r   r   r   r#   r3   r7   r;   r   r@   rR   rb   rf   rl   Modulerm   r   r   r   r   r   r   r   r   r?  rK  rW  r!   r!   r!   r"   <module>   sN    
"	
R T4=tc2