o
    iH                     @   s2  d Z ddlm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
mZ ddlmZ ddlmZmZmZmZmZmZmZ ddlmZmZmZmZmZ dd	lmZmZmZ ej j!d
dddej"j#ddej$j!dddgdddej$j!dg ddddgZ%dd Z&dAde'fddZ(							dBd e)ej* d!e+fd"d#Z,d$ed%e-fd&d'Z.d$ed%e'dB fd(d)Z/d*e-d e)ej* d%efd+d,Z0d-e-d e)ej* d%efd.d/Z1d0e-d%e2e-dB ej3dB f fd1d2Z4G d3d4 d4ej*Z5G d5d6 d6ej*Z6G d7d8 d8ej*Z7G d9d: d:ej*Z8G d;d< d<ej*Z9G d=d> d>eZ:d%e:fd?d@Z;dS )CzU
ComfyUI X Rodin3D(Deemos) API Nodes

Rodin API docs: https://developer.hyper3d.ai/

    )cleandocN)BytesIO)override)Image)Rodin3DGenerateRequestRodin3DGenerateResponseRodin3DCheckStatusRequestRodin3DCheckStatusResponseRodin3DDownloadRequestRodin3DDownloadResponse	JobStatus)sync_oppoll_opApiEndpointdownload_url_to_bytesiodownload_url_to_file_3d)ComfyExtensionIOTypesSeed  Tdefaultminmaxdisplay_modeoptionalMaterial_TypePBRShadedoptionsr   r   Polygon_count)4K-Quad8K-Quad18K-Quad50K-Quadz200K-Triangler%   c                 C   s   |  d}|d }|d }|dkrd}n	|dkrd}nd}|dkr'd}||fS |d	kr1d
}||fS |dkr;d}||fS |dkrEd}||fS |dkrOd}||fS |dkrYd}||fS |dkrcd}||fS |dkrmd}||fS d}||fS )N-   r   TriangleRawQuad4Ki  8Ki@  18KPF  50KiP  2Ki  20Ki N  150KiI 500Ki  )split)
poly_count	polycountpolycount	mesh_modequality_override r<   9/mnt/c/Users/fbmor/ComfyUI/comfy_api_nodes/nodes_rodin.pyget_quality_mode6   sD   

r>     @ 
max_pixelsc                 C   s   |    }|d d}t|d}|j\}}|| }||kr4t|| }t|| }t|| }	n||}}	||ksA|	|krK|	||	ftj
j}t }
|j|
dd |
d |
S )a4  
    Converts a PyTorch tensor to a file-like object.

    Args:
    - tensor (torch.Tensor): A tensor representing an image of shape (H, W, C)
      where C is the number of channels (3 for RGB), H is height, and W is width.

    Returns:
    - io.BytesIO: A file-like object containing the image data.
       uint8RGBPNG)formatr   )cpunumpyastyper   	fromarraysizemathsqrtintresize
ResamplingLANCZOSr   saveseek)tensorr@   arrayimageoriginal_widthoriginal_heightoriginal_pixelsscale	new_width
new_heightimg_byte_arrr<   r<   r=   tensor_to_filelikeW   s    


r]   r(   r/   Regularr+   Fclsta_posec                    s   |d u r	t dt|dkrt dt| tdddtt||||||ddd	 |D d
dI d H }t|drId|j d|j }	t	|	 t |	t	
d |jj}
|j}t	
d| ||
fS )Nz,Rodin 3D generate requires at least 1 image.   z)Rodin 3D generate requires up to 5 image.z/proxy/rodin/api/v2/rodinPOSTpathmethod)seedtiermaterialr;   r:   TAPosec                 S   s4   g | ]}|d urdt |trt|dnt|fqS )Nimagesrb)
isinstancestropenr]   ).0rU   r<   r<   r=   
<listcomp>   s    
z(create_generate_task.<locals>.<listcomp>zmultipart/form-data)response_modeldatafilescontent_typeerrorz1Rodin3D Create 3D generate Task Failed. Message: z	, error: z;[ Rodin3D API - Submit Jobs ] Submit Generate Task Success!z&[ Rodin3D API - Submit Jobs ] UUID: %s)	Exceptionlenr   r   r   r   hasattrmessageru   logginginfojobssubscription_keyuuid)r_   rj   rf   rh   r;   rg   r:   r`   responseerror_messager}   	task_uuidr<   r<   r=   create_generate_taskx   s>   




r   r   returnc                 C   sd   t dd | jD }dd | jD }td| tdd | jD r,td| td|r0d	S d
S )Nc                 s       | ]	}|j tjkV  qd S Nstatusr   Donero   jobr<   r<   r=   	<genexpr>       z%check_rodin_status.<locals>.<genexpr>c                 S   s   g | ]}t |jqS r<   )rm   r   r   r<   r<   r=   rp      s    z&check_rodin_status.<locals>.<listcomp>z1[ Rodin3D API - CheckStatus ] Generate Status: %sc                 s   r   r   )r   r   Failedr   r<   r<   r=   r      r   zD[ Rodin3D API - CheckStatus ] Generate Failed: %s, Please try again.z2[ Rodin3D API ] Generate Failed, Please Try again.DONE
Generating)allr|   rz   r{   anyru   rv   )r   all_donestatus_listr<   r<   r=   check_rodin_status   s   r   c                 C   s4   | j sd S tdd | j D }t|t| j  d S )Nc                 s   s     | ]}|j tjkrd V  qdS )r(   Nr   r   r<   r<   r=   r      s    z#extract_progress.<locals>.<genexpr>d   )r|   sumrM   rw   )r   completed_countr<   r<   r=   extract_progress   s   r   r}   c                    s4   t d t|tdddtt| dttdI d H S )Nz-[ Rodin3D API - CheckStatus ] Generate Start!z/proxy/rodin/api/v2/statusrb   rc   )r}   )rq   rr   status_extractorprogress_extractor)rz   r{   r   r   r	   r   r   r   )r}   r_   r<   r<   r=   poll_for_task_status   s   

r   r~   c                    s2   t d t|tdddtt| dddI d H S )Nz4[ Rodin3D API - Downloading ] Generate Successfully!z/proxy/rodin/api/v2/downloadrb   rc   )r   F)rq   rr   monitor_progress)rz   r{   r   r   r   r
   )r~   r_   r<   r<   r=   get_rodin_download_list   s   

r   r   c           	   	      s   d| }t jt |}t j|dd d }d }| jD ]I}t j||j}|j 	dr]t j||j}t
|jdI d H }t|d}||  W d    n1 sWw   Y  qt|j|I d H  q||fS )NRodin3D_T)exist_okz.glbglbwb)osrd   joincomfy_pathsget_output_directorymakedirslistnamelowerendswithr   urlrn   write	get_bytesr   )	url_listr   result_folder_name	save_pathmodel_file_pathfile_3di	file_pathfr<   r<   r=   download_files   s"   

r   c                   @   8   e Zd ZdZedejfddZedejfddZ	dS )Rodin3D_Regular"Generate 3D Assets using Rodin APIr   c                 C   f   t jdddt| jp
dt jdgtt jjddt j	jddgt j
jt j
jt j
jgd	t jd
dd	S )Nr   z$Rodin 3D Generate - Regular Generateapi node/3d/Rodin Images3D Model Pathdisplay_nameGLBT{"type":"usd","usd":0.4}expr	node_idr   categorydescriptioninputsoutputshiddenis_api_nodeprice_badger   Schemar   __doc__r   InputCOMMON_PARAMETERSStringOutput	File3DGLBHiddenauth_token_comfy_orgapi_key_comfy_org	unique_id
PriceBadger_   r<   r<   r=   define_schema   *   
zRodin3D_Regular.define_schemac              	         d}|j d }g }t|D ]	}|||  qt|\}	}
t| ||||
||	dI d H \}}t|| I d H  t|| I d H }t||I d H \}}t	||S )Nr^   r   rj   rf   rh   r;   rg   r:   
shaperangeappendr>   r   r   r   r   r   
NodeOutputr_   r   r   r   r"   rg   
num_imagesm_imagesr   r:   r;   r   r}   download_list
model_pathr   r<   r<   r=   execute  (   
	zRodin3D_Regular.executeN
__name__
__module____qualname__r   classmethodr   r   r   r   r   r<   r<   r<   r=   r          r   c                   @   r   )Rodin3D_Detailr   r   c                 C   r   )Nr   z#Rodin 3D Generate - Detail Generater   r   r   r   r   r   Tr   r   r   r   r   r<   r<   r=   r   %  r   zRodin3D_Detail.define_schemac              	      r   )NDetailr   r   r   r   r<   r<   r=   r   ?  r   zRodin3D_Detail.executeNr   r<   r<   r<   r=   r   "  r   r   c                   @   r   )Rodin3D_Smoothr   r   c                 C   r   )Nr   z#Rodin 3D Generate - Smooth Generater   r   r   r   r   r   Tr   r   r   r   r   r<   r<   r=   r   `  r   zRodin3D_Smooth.define_schemac              	      s   |j d }g }t|D ]	}|||  qt|\}}	t| ||||	d|dI d H \}
}t|| I d H  t|
| I d H }t||
I d H \}}t	||S )Nr   Smoothr   r   )r_   r   r   r   r"   r   r   r   r:   r;   r   r}   r   r   r   r<   r<   r=   r   z  s&   
	zRodin3D_Smooth.executeNr   r<   r<   r<   r=   r   ]  r   r   c                   @   r   )Rodin3D_Sketchr   r   c                 C   s|   t jdddt| jp
dt jdt jjddddt jjd	d
gt j	j
ddt jj
ddgt jjt jjt jjgd	t jddd	S )Nr   z#Rodin 3D Generate - Sketch Generater   r   r   r   r   r   Tr   r   r   r   r   r   r   )r   r   r   r   r   r   IntNumberDisplaynumberr   r   r   r   r   r   r   r   r   r<   r<   r=   r     s6   
zRodin3D_Sketch.define_schemac              	      s   |j d }g }t|D ]	}|||  qt| ||dddddI d H \}}t|| I d H  t|| I d H }t||I d H \}	}
t|	|
S )Nr   r   r/   Sketchr+   r   )	r   r   r   r   r   r   r   r   r   )r_   r   r   r   r   r   r   r}   r   r   r   r<   r<   r=   r     s$   
	zRodin3D_Sketch.executeNr   r<   r<   r<   r=   r     s     r   c                   @   r   )Rodin3D_Gen2r   r   c                 C   s   t jdddt| jp
dt jdt jjddddt jjd	d
t j	jdddgdd	dt j	jdg ddd	dt j
jddd	dgt jjddt jjddgt jjt jjt jjgd	t jddd	S )Nr   z"Rodin 3D Generate - Gen-2 Generater   r   r   r   r   r   Tr   r   r   r   r    r"   )r#   r$   r%   r&   z2K-Trianglez20K-Trianglez150K-Triangle500K-Triangler   ri   F)r   advancedr   r   r   r   r   r   )r   r   r   r   r   r   r   r   r   ComboBooleanr   r   r   r   r   r   r   r   r   r<   r<   r=   r     sF   
zRodin3D_Gen2.define_schemac              
      s   d}|j d }g }t|D ]	}	|||	  qt|\}
}t| ||||||
|dI d H \}}t|| I d H  t|| I d H }t||I d H \}}t	||S )NzGen-2r   )rj   rf   rh   r;   rg   r:   r`   r   )r_   r   r   r   r"   ri   rg   r   r   r   r:   r;   r   r}   r   r   r   r<   r<   r=   r     s*   	

zRodin3D_Gen2.executeNr   r<   r<   r<   r=   r     s    (r   c                   @   s(   e Zd Zedeeej  fddZdS )Rodin3DExtensionr   c                    s   t ttttgS r   )r   r   r   r   r   )selfr<   r<   r=   get_node_list"  s   zRodin3DExtension.get_node_listN)	r   r   r   r   r   typer   	ComfyNoder  r<   r<   r<   r=   r   !  s    r   c                      s   t  S r   )r   r<   r<   r<   r=   comfy_entrypoint-  s   r  )r?   )Nr(   r   r/   r^   r+   F)<r   inspectr   folder_pathsr   r   rz   rK   ior   typing_extensionsr   PILr   comfy_api_nodes.apis.rodinr   r   r   r	   r
   r   r   comfy_api_nodes.utilr   r   r   r   r   comfy_api.latestr   r   r   r   r   r   r   r   r   r>   rM   r]   r  r  boolr   rm   r   r   r   r   tupleFile3Dr   r   r   r   r   r   r   r  r<   r<   r<   r=   <module>   sl    $	!#
1$;;:>L