o
    i[                     @   s>  d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlZd dl	Z
d dlmZ d dlmZ d dlmZmZmZ d dlmZmZ G dd dejZG d	d
 d
ejZG dd dejZG dd dejZd!ddZd!ddZG dd dejZG dd dejZd"ddZG dd dejZ G dd deZ!de!fdd Z"dS )#    N)'get_1d_sincos_pos_embed_from_grid_torch)args)override)ComfyExtensionIOTypes)MESHVOXELc                   @   0   e Zd Zedd ZedejfddZeZdS )EmptyLatentHunyuan3Dv2c                 C   s@   t jddt jjdddddt jjdddd	d
dgt j gdS )Nr   	latent/3d
resolutioni      i    )defaultminmax
batch_sizei   z)The number of latent images in the batch.)r   r   r   tooltipnode_idcategoryinputsoutputs)r   SchemaIntInputLatentOutputcls r    :/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_hunyuan3d.pydefine_schema   s   z$EmptyLatentHunyuan3Dv2.define_schemareturnc                 C   s*   t j|d|gtj d}t|ddS )N@   devicehunyuan3dv2)samplestype)torchzeroscomfymodel_managementintermediate_devicer   
NodeOutput)r   r   r   latentr    r    r!   execute   s   zEmptyLatentHunyuan3Dv2.executeN)	__name__
__module____qualname__classmethodr"   r   r/   r1   generater    r    r    r!   r      s    
r   c                   @   r
   )Hunyuan3Dv2Conditioningc                 C   s4   t jddt jdgt jjddt jjddgdS )Nr7   conditioning/video_modelsclip_vision_outputpositivedisplay_namenegativer   r   r   ClipVisionOutputr   Conditioningr   r   r    r    r!   r"   '   s   
z%Hunyuan3Dv2Conditioning.define_schemar#   c                 C   s,   |j }|i gg}t|i gg}t||S N)last_hidden_stater*   
zeros_liker   r/   )r   r9   embedsr:   r=   r    r    r!   r1   5   s   
zHunyuan3Dv2Conditioning.executeN	r2   r3   r4   r5   r"   r   r/   r1   encoder    r    r    r!   r7   &   s    
r7   c                   @   s2   e Zd Zedd ZeddejfddZeZdS ) Hunyuan3Dv2ConditioningMultiViewc              
   C   sb   t jddt jjdddt jjdddt jjdddt jjdddgt jjd	d
t jjdd
gdS )NrG   r8   frontT)optionalleftbackrightr:   r;   r=   r   r>   r   r    r    r!   r"   @   s   z.Hunyuan3Dv2ConditioningMultiView.define_schemaNr#   c              	   C   s   ||||g}g }d }t |D ]'\}}	|	d ur5|d u r&t|	jjd td}||	j|| ddd  qtj|dd}
|
i gg}t	|
i gg}t
||S )N   r   dim)	enumerater   rB   shaper*   arangeappendreshapecatrC   r   r/   )r   rH   rJ   rK   rL   
all_embedsout
pos_embedsierD   r:   r=   r    r    r!   r1   Q   s   
z(Hunyuan3Dv2ConditioningMultiView.execute)NNNNrE   r    r    r    r!   rG   ?   s    
rG   c                   @   r
   )VAEDecodeHunyuan3Dc                 C   sV   t jddt jdt jdt jjddddd	d
t jjddddd	d
gt j gdS )Nr\   r   r(   vae
num_chunksi@  i  i  T)r   r   r   advancedoctree_resolution      i   r   )r   r   r   r   Vaer   Voxelr   r   r    r    r!   r"   e   s   

z VAEDecodeHunyuan3D.define_schemar#   c                 C   s(   t |j|d ||dd}t|S )Nr(   )r^   r`   )vae_options)r   r	   decoder   r/   )r   r]   r(   r^   r`   voxelsr    r    r!   r1   u   s   
zVAEDecodeHunyuan3D.executeN	r2   r3   r4   r5   r"   r   r/   r1   rf   r    r    r    r!   r\   d   s    
r\         ?c           "      C   s  |d u r	t d}| |} | |k }t jj|ddd}|j\}}}t jg dg dg dg dg d	g d
g|d}t j	t j
||dt j
||dt j
||ddd\}	}
}t j|	 |
 | gdd}| dk}|| }t jg dg dg dg dg|dt jg dg d	g dg dg|dt jg dg dg dg dg|dt jg dg dg dg d	g|dt jg dg dg dg d	g|dt jg dg dg dg dg|dg}g }g }d}t|D ]\}}|| }|d }||d d df |d d df |d d df f dk}| sq|| }|| d}|d| }||dd |jd }t j
||d|  |ddd}|t j|d d df |d d df |d d df gdd |t j|d d df |d d df |d d df gdd |d| 7 }qt|dkrt j|dd}t j|dd}n
t d}t d}d}t| j} |||  d  }| | d }!|!dkr||! }t |}||fS )Ncpur   r   r   r   r   r   constantr   r   r   r   )r   r   rM   r   r   r   )r   rM   r   r   r   r   )rM   r   r   r%   ijindexingr   rO   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      rM      rN   r   ry   )r*   r&   tofloatnn
functionalpadrR   tensormeshgridrS   stackflattenrQ   any	unsqueezerT   rU   lenrV   r+   r   fliplr)"rg   	thresholdr&   binarypaddedDHW	neighborszyxvoxel_indices
solid_masksolid_indicescorner_offsetsall_verticesall_indicesvertex_countface_idxoffsetneighbor_indicespadded_indices
is_exposedexposed_indicescornersface_vertices	num_facesface_indicesverticesfacesv_minv_maxscaler    r    r!   voxel_to_mesh}   s   

	 


>>




r   c           U         sT  |d u r	t d}| |} | j\}}}t jj| ddd}t jt j||dt j||dt j||ddd\}}}	t j	|
 |
 |	
 gdd	}
t jg d
g dg dg dg dg dg dg dg|d}|
d|d }|d\}}}||||f }||k}t j|dd	}t j| dd	}||@ }|
| }|| }|| }|jd dkrt jd|dt jdt j|dfS t jddgddgddgddgddgddgddgddgddgddgddgddgg|d}i }tjd}t|D ]\}\}}|d |d d |f |d d |f k}| sqt j|ddd }|||f } |||f }!t j| |d}"|!|  }#|#dk}$|| |$  |#|$  |"|$< d|"|$ < ||  }%||  }&|%d|"d|&d|%d   }'t| |'D ]\}(})|(|vr|g ||(< ||( |) qoqg }*i }+tt|d },| D ]4\}(}-|(|, s|d |-rt 	|-jdd	}.|.||(   }.t|*|+t ||(  < |*|. q|*st jd|dt jdt j|dfS t 	|*}/|}0| }1|0j!ddd  }2|1j!ddd  }3t j|jd df|d}4t j|jd df|d}5t"d!D ]3}(|0d d |(f d}6|1d d |(f d}7|4||(  d|6 7 }4|5||(  d|7 7 }5q|4|2 }4|5|3 }5|4|5 }8t jg dg dg dg|d  fd"d#t"dD }9g }:t#|+$ };tt|d$ d }<tg d%D ]\}=\}(}> |( }? |> }@|9|= }A||? }B||@ }C||? |@ }Dt %|8|A}Eg }Fg }Gt|D ]_\}H}I|H|< s|d t |I }Jt |B|H  }Kt |C|H  }Lt |D|H  }M|J|;v r|K|;v r|L|;v r|M|;v r|+|J }N|+|K } |+|L }!|+|M }O|F|N| |!|Of |G|H qt|FD ]R\}P\}N} }!}O|G|P }Q|E|Q dkrN|:t j|N| |Og|t jd& |:t j|N|O|!g|t jd& q|:t j|N|O| g|t jd& |:t j|N|!|Og|t jd& qq|:ryt 	|:}:n	t jdt j|d}:d}Rt&|||}S|/|R|S d  }/|S|R d }T|Tdkr|/|T }/t '|/}/|/|:fS )'Nrj   rk   rl   r   r%   rp   rq   r   rO   rv   ro   rn   rw   rm   ru   rs   rt   rM   )r   ry   )dtyper&   rx   rN   ry            d   T)as_tupleri   2   )rP   keepdim   c                    s>   g | ]}t |d  dD ]}tj |   |  qqS rz   )ranger*   linalgcrossr|   ).0rZ   jpos_dirsr    r!   
<listcomp>a  s    z)voxel_to_mesh_surfnet.<locals>.<listcomp>&   ))r   r   )r   rx   )r   rx   )r&   r   )(r*   r&   r{   rR   r}   r~   r   r   rS   r   r   r   r   unbindr   r+   longr,   utilsProgressBarrQ   updatenonzerorC   r|   ziptolistrT   roundr   itemsmeantuplesumr   setkeysmatmulr   r   )Urg   r   r&   r   r   r   r   r   r   r   cell_positionsr   posz_idxy_idxx_idxcorner_valuescorner_signs
has_insidehas_outsidecontains_surfaceactive_cellsactive_signsactive_valuesedgescell_verticesprogressedge_idxe1e2crossingcell_indicesv1v2tdenomvalidp1p2intersectionrZ   pointr   vertex_lookupvert_progress_modpointsvertexfinal_verticesinside_corners_maskoutside_corners_maskinside_countsoutside_counts
inside_posoutside_posmask_insidemask_outside	gradientscross_productsr   all_keysface_progress_modpair_idxr   dir_idir_jcross_productni_positionsnj_positionsdiag_positions
alignmentsvalid_quadsquad_indicesidxactive_cellcell_keyni_keynj_keydiag_keyv0v3q_idxcell_idxr   r   r   r    r   r!   voxel_to_mesh_surfnet   s$  

  
 

(



 



(
""	

r  c                   @   r
   )VoxelToMeshBasicc                 C   s8   t jddt jdt jjdddddd	gt j gd
S )Nr  3dvoxelr   333333?            ?{Gz?r   r   r   stepr   )r   r   rd   r   FloatMeshr   r   r    r    r!   r"     s   
zVoxelToMeshBasic.define_schemar#   c                 C   sX   g }g }|j D ]}t||d d\}}|| || qttt|t|S )Nr   r&   )	datar   rT   r   r/   r   r   r*   r   )r   r  r   r   r   r   vfr    r    r!   r1     s   

zVoxelToMeshBasic.executeNrh   r    r    r    r!   r    s    

r  c                   @   r
   )VoxelToMeshc                 C   sL   t jddt jdt jjdddgddt jjd	d
ddddgt j gdS )Nr  r  r  	algorithmsurface netbasicT)optionsr_   r   r  r  r  r  r  r   )r   r   rd   r   Combor  r  r   r   r    r    r!   r"     s   
zVoxelToMesh.define_schemar#   c           
      C   sr   g }g }|dkrt }n|dkrt}|jD ]}|||d d\}}	|| ||	 qttt	|t	|S )Nr!  r   r  )
r   r  r  rT   r   r/   r   r   r*   r   )
r   r  r  r   r   r   mesh_functionr   r  r  r    r    r!   r1     s   

zVoxelToMesh.executeNrh   r    r    r    r!   r    s    
r  c                 C   s  |    tj}|   tj}| }| }dd }||}	||}
|	|
 }t|}d}t|}t|	}ddddt|igd||dd	d||d
d	gdddt|d|jdd	 |j
dd	 dddd|jddgdddidddgigddigddgigdd}|dur||d d< t|d}dd }||}td d!d"d#t| d$ t| }td%t|d&}td%t|d'}t|d("}|| || || || || W d   |S 1 sw   Y  |S ))a9  
    Save PyTorch tensor vertices and faces as a GLB file without external dependencies.

    Parameters:
    vertices: torch.Tensor of shape (N, 3) - The vertex coordinates
    faces: torch.Tensor of shape (M, 3) - The face indices (triangle faces)
    filepath: str - Output filepath (should end with .glb)
    c                 S       dt | d  d }| d|  S )NrN       r   bufferpadding_lengthr    r    r!   pad_to_4_bytes     z save_glb.<locals>.pad_to_4_bytesr   z2.0ComfyUI)version	generator
byteLengthi  )r)  
byteOffsetr0  targeti  i  VEC3)axis)
bufferViewr1  componentTypecountr)   r   r   r   i  SCALAR)r5  r1  r6  r7  r)   
primitivesPOSITIONrN   )
attributesindicesmodemeshnodes)assetbuffersbufferViews	accessorsmeshesr?  scenessceneNr@  extrasutf8c                 S   r%  )NrN       r'  r(  r    r    r!   pad_json_to_4_bytesM  r,  z%save_glb.<locals>.pad_json_to_4_bytesz<4sIIs   glTFrx      r   z<IIiJSONiBIN wb)rj   numpyastypenpfloat32uint32tobytesr   r   r   r   sizejsondumpsrF   structpackopenwrite)r   r   filepathmetadatavertices_npfaces_npvertices_bufferindices_bufferr+  vertices_buffer_paddedindices_buffer_paddedbuffer_datavertices_byte_lengthvertices_byte_offsetindices_byte_lengthindices_byte_offsetgltf	gltf_jsonrJ  gltf_json_padded
glb_headerjson_chunk_headerbin_chunk_headerr  r    r    r!   save_glb  s   
A$




rm  c                   @   s<   e Zd Zedd ZedejejB dede	j
fddZdS )	SaveGLBc                 C   sl   t jddddgdddt jjt jdt jt jt jt jt j	t j
t jgd	d
t jjdddgt jjt jjgdS )Nrn  zSave 3D Modelzexport 3d modelz	save meshr  BasicsTr>  zMesh or 3D file to save)typesr   filename_prefixzmesh/ComfyUI)r   )r   r<   search_aliasesr   essentials_categoryis_output_noder   hidden)r   r   	MultiTyper   r  	File3DGLB
File3DGLTF	File3DOBJ	File3DFBX	File3DSTL
File3DUSDZ	File3DAnyStringHiddenpromptextra_pnginfor   r    r    r!   r"   i  s.   
	zSaveGLB.define_schemar>  rq  r#   c                 C   s@  t |t  \}}}}}g }i }tjs;| jjd ur#t| jj|d< | jj	d ur;| jj	D ]}	t| jj	|	 ||	< q-t
|tjre|jpEd}
| d|dd|
 }|tj|| |||dd n3t|jjd D ]*}| d|dd	}t|j| |j| tj||| |||dd |d
7 }qmtjd|idS )Nr  glb_05z_.output)filename	subfolderr)   r   z_.glbr   r  )ui)folder_pathsget_save_image_pathget_output_directoryr   disable_metadataru  r  rT  rU  r  
isinstancer   File3Dformatsave_toospathjoinrT   r   r   rR   rm  r   r   r/   )r   r>  rq  full_output_folderr  counterr  resultsr[  r   extr  rZ   r    r    r!   r1     s8   

$
zSaveGLB.executeN)r2   r3   r4   r5   r"   r   r   r  strr   r/   r1   r    r    r    r!   rn  h  s
    
&rn  c                   @   s(   e Zd Zedeeej  fddZdS )Hunyuan3dExtensionr#   c                    s   t ttttttgS rA   )r   r7   rG   r\   r  r  rn  )selfr    r    r!   get_node_list  s   z Hunyuan3dExtension.get_node_listN)	r2   r3   r4   r   listr)   r   	ComfyNoder  r    r    r    r!   r    s    r  r#   c                      s   t  S rA   )r  r    r    r    r!   comfy_entrypoint  s   r  )ri   NrA   )#r*   r  rT  rV  rM  rO  (comfy.ldm.modules.diffusionmodules.mmditr   r  comfy.model_managementr,   comfy.cli_argsr   typing_extensionsr   comfy_api.latestr   r   r   comfy_api.latest._utilr   r	   r  r   r7   rG   r\   r   r  r  r  rm  rn  r  r  r    r    r    r!   <module>   s4    %

m =
$ B