
    +jL                     F   S r SSKrSSKrSSKrSSKJrJrJr  SSK	J
r
  SSKJr  SSKJr  SSKJr  SSKJrJrJrJrJr  SSKrSS	KJr  \R6                  " S
5      r\R6                  " S5      rS\R<                  S\R<                  4S jrS\R<                  S\R<                  4S jr  " S S\RB                  5      r" " S S\RB                  5      r# " S S\RB                  5      r$ " S S\RB                  5      r% " S S\RB                  5      r& " S S\5      r'S\'4S jr(g)zNComfyUI nodes for the native MoGe (Monocular Geometry Estimation) integration.    N)ComfyExtensionTypesio)override)turbo)	MoGeModel)triangulate_grid_mesh)get_panorama_camerassplit_panorama_imagemerge_panorama_depthspherical_uv_to_directions_uv_grid)tqdm
MOGE_MODELMOGE_GEOMETRYpointsreturnc                 b   [         R                  " U 5      R                  SS9n[         R                  " UR	                  S5      U [         R
                  " U 5      5      nUSSS2SS2SS24   USSS2SS2SS24   -
  nUSSS2SS2SS24   USSS2SS2SS24   -
  n[         R                  R                  R                  UR                  SSS	S5      S
5      R                  SSSS	5      n[         R                  R                  R                  UR                  SSS	S5      S5      R                  SSSS	5      n[         R                  " XCSS9n[         R                  R                  R                  USS9n[         R                  " UR	                  S5      U[         R
                  " U5      5      $ )zICamera-space surface normals from a (B, H, W, 3) point map (v1 fallback).dim.N   r         )r   r   r   r   )r   r   r   r   )torchisfiniteallwhere	unsqueeze
zeros_likenn
functionalpadpermutecross	normalize)r   finiteptsdxdyns         7/home/wildlama/comfy/ComfyUI/comfy_extras/nodes_moge.py_normals_from_pointsr.      sp   ^^F#''B'/F
++f&&r*FE4D4DV4L
MC	S!QR]	c#q#2#q.1	1B	S!"a]	c#ssAq.1	1B				 	 Aq!Q!7	F	N	NqRSUVXY	ZB				 	 Aq!Q!7	F	N	NqRSUVXY	ZBB#A%%aR%0A;;v''+Q0@0@0CDD    depthc                 p   [         R                  " U 5      n[        U R                  S   5       GH  nX   n[         R                  " U5      US:  -  nUR                  5       (       d  M;  [         R                  " USUR                  S5      -  [         R                  " U5      5      nXT   n[         R                  " US5      n[         R                  " US5      nX-
  R                  S5      n	XW-
  U	-  R                  SS5      n
[         R                  " XJ[         R                  " U
5      5      X'   GM     U$ )zIPer-batch normalize 1/depth to [0, 1] using 0.1/99.9 percentile clipping.r         ?gư>gMbP?g+?        )
r   r!   rangeshaper   anyr   	clamp_minquantileclamp)r0   outidvaliddisp
disp_validlohiscalenorms              r-   _normalize_disparityrD   -   s    


5
!C5;;q>"Hq!QU+yy{{{{5#D(9"95;K;KA;NO[
^^J.^^J.##D)e#**34U%*:*:4*@A # Jr/   c                   P    \ rS rSr\S 5       r\S\R                  4S j5       rSr	g)LoadMoGeModel?   c                     [         R                  " SSS[         R                  R                  S[        R
                  " S5      S9/[        R                  5       /S9$ )NrF   zLoad MoGe Modelzmodel/loaders
model_namegeometry_estimation)options)node_iddisplay_namecategoryinputsoutputs)r   SchemaComboInputfolder_pathsget_filename_listMoGeModelTypeOutputclss    r-   define_schemaLoadMoGeModel.define_schema@   sR    yy#*$|\5S5STi5jk #))+,
 	
r/   r   c                     [         R                  " SU5      n[        R                  R	                  USS9n[
        R                  " [        U5      5      $ )NrJ   T)	safe_load)rT   get_full_path_or_raisecomfyutilsload_torch_filer   
NodeOutputr   )rY   rI   pathsds       r-   executeLoadMoGeModel.executeL   sA    223H*U[[(((>}}Yr]++r/    N
__name__
__module____qualname____firstlineno__classmethodrZ   r   rb   re   __static_attributes__rg   r/   r-   rF   rF   ?   s3    	
 	
 ,BMM , ,r/   rF   c                   T    \ rS rSrSr\S 5       r\S\R                  4S j5       r	Sr
g)MoGePanoramaInferenceS   zEquirectangular panorama inference: split into 12 perspective views, run
MoGe at fov_x=90 on each, merge via multi-scale Poisson + gradient solve.
v2's predicted normals and metric scale are ignored (per-view scales would not align across seams).
c                    [         R                  " S/ SQSSS[        R                  S5      [         R                  R                  SSS	9[         R
                  R                  S
SSSSS9[         R
                  R                  SSSSSS9[         R
                  R                  SSSSSS9[         R
                  R                  SSSSSS9/[        R                  SS9/S9$ ) Nrp   )mogepanoramar0   geometrydepth estimationgeometry estimationzRun MoGe Panorama Inferenceimage/geometry estimationzRun MoGe on an equirectangular panorama by splitting it into 12 perspective views, running inference on each, and merging the results into a single depth map.
moge_modelimagez&Equirectangular panorama (any aspect).)tooltipresolution_level	   r   z1Per-view detail (0 = fastest, 9 = most detailed).defaultminmaxr{   split_resolutioni      i   z%Resolution of each perspective split.merge_resolutioni  i    z9Long-side resolution of the merged equirect distance map.
batch_size   r      z,Views per inference batch (12 splits total).moge_geometryrM   )rL   search_aliasesrM   rN   descriptionrO   rP   )r   rQ   rV   rS   ImageIntMoGeGeometryrW   rX   s    r-   rZ   #MoGePanoramaInference.define_schemaY   s    yy+o60 y##L1w0XY/q%X  Z/#4%L  N/3D%`  b\1!%S  U "((o(FG%
 	
r/   r   c                 ,
  ^)^*^+^, UR                   S   S:w  a  [        SUR                   S    S35      eUSS S24   n[        UR                   S   5      [        UR                   S   5      p[        U[	        Xx5      -  S5      n	[	        [        Xy-  5      S	5      [	        [        X-  5      S	5      p[        5       u  p[        R                  R                  UR                  5        UR                  nUS   R                  S
S5      R                  XR                  S9n[        XX5      nUR                   S   n/ nXnn UR                  UU45        [	        UU5      S::  a  OUS-  US-  nnM0  UR!                  5         [#        U5       VVs0 s H  u  nnUSU-  _M     snnm+U[%        U5      -  n['        T+R)                  5       5      n[        R*                  R-                  UU-   U-   5      m*Sm)/ n/ n[/        USS9 m,[1        SUU5       H  nUUUU-    nUR3                  UUSSSSS9nUR5                  [7        US   R9                  5       R;                  S
S9R=                  5       R?                  5       5      5        UR5                  [7        US   R=                  5       R?                  5       5      5        UR                   S   nT)U-  m)T*RA                  T)5        T,RC                  U5        M     S S S 5        [/        UU-   SS9 m,U)U*U,4S jnU,4S jnU)U*U+U,4S jn [E        XUU[7        U5      UUUU S9	u  n!n"S S S 5        [F        RH                  " W!5      n![F        RH                  " W"5      n"X4Xx4:w  a  [F        RJ                  RL                  RO                  U!S   Xx4SSS9RQ                  5       n![F        RJ                  RL                  RO                  U"S   R9                  5       Xx4S S!9RQ                  5       S:  n"U"RS                  5       (       aJ  U"RU                  5       (       d5  [F        RV                  " U!U"   S"5      S#-  n#[F        RX                  " U"U!U#5      n![F        RH                  " [[        []        Xx5      5      5      n$U$U!S$   -  R_                  S5      n%U!R_                  S5      n&U"R_                  S5      n'U%U&U'UR=                  5       S%.n([`        Rb                  " U(5      $ s  snnf ! , (       d  f       GN= f! , (       d  f       GN= f)&Nr   r   z9MoGePanoramaInference takes a single image (got batch of ).r   r   r2       r   devicedtypeTr   r   zMoGe panorama inferencetotaldescg     V@F)r|   fov_xforce_projection
apply_maskapply_metric_scaler   r   maskMoGe panorama merge: viewsc                  T   > T S-  m TR                  T 5        TR                  S5        g )Nr   )update_absoluteupdate)donepbartqs   r-   _on_merge_view5MoGePanoramaInference.execute.<locals>._on_merge_view   s%    	$$T*		!r/   c                 4   > TR                  SU  SU 35        g )NzMoGe panorama merge: solving x)set_description)whr   s     r-   _on_solve_start6MoGePanoramaInference.execute.<locals>._on_solve_start   s    ""%B1#Qqc#JKr/   c                    > TX4   nTU-  mTR                  T5        TR                  U5        TR                  S5        g )Nr   )r   r   r   )r   r   weightr   r   solve_weightr   s      r-   _on_solve_end4MoGePanoramaInference.execute.<locals>._on_solve_end   sA    %qf-$$T*		&!""#?@r/   )on_viewon_solve_starton_solve_end)NNbilinear)sizemodealign_cornersnearest)r   r   gffffff?g      @).N)r   r0   r   rz   )2r5   
ValueErrorintr   r   r
   r_   model_managementload_model_gpupatcherload_devicemovedimtor   r   appendreverse	enumeratelensumvaluesr`   ProgressBarr   r4   inferextendlistfloatrC   cpunumpyr   r   r   r   
from_numpyr"   r#   interpolatesqueezer6   r   r8   r   r   r   r    r   rb   )-rY   ry   rz   r|   r   r   r   HWrB   merge_hmerge_w
extrinsics
intrinsicsr   img_chwsplitsn_viewsmerge_levelsw_h_r;   whn_merge_view_unitsn_merge_solve_unitsdistance_mapsmasksbatchresultr,   r   r   r   
pano_depth	pano_maskfar
directionsr   r0   r   r   r   r   r   r   s-                                            @@@@r-   re   MoGePanoramaInference.executep   s    ;;q>QXY^YdYdefYgXhhijkkc2A2g5;;q>"CA$71$s1y0#6s19~r2CAI4K!5!7
--j.@.@A''(""2r*--VCSCS-T%g:X,,q/ /1BR)2r{c!1WbAgB	 
 	09,0GH0Guq"AF
0GH$s<'88!,"5"5"78{{&&w1C'CFY'YZ &?@B1gz2qZ0#))%BR04t5:u * V $$T&*:*@*@*B*G*GB*G*O*S*S*U*[*[*]%^_T&."4"4"6"<"<">?@KKN	$$T*		! 3 A *-@@GcdhjLA A %9-Z8H*&Ub%d!J	% e, %%j1
$$Y/	!',,88J9OWXV\cm  ~C8  D  L  L  NJ++77	*8M8S8S8U]^\bir7s{{}  AB  BI ==??9==??..I!6=CCY
C@J%%&@!&PQ
z)44??B$$Q'""1% $*E4RWR[R[R]^}}]++A I A@ eds   S, C4S2	4T2
T
Trg   Nri   rj   rk   rl   __doc__rm   rZ   r   rb   re   rn   rg   r/   r-   rp   rp   S   s@    
 
 
, ],momzmz ], ],r/   rp   c                   P    \ rS rSr\S 5       r\S\R                  4S j5       rSr	g)MoGeInference   c                     [         R                  " S/ SQSSS[        R                  S5      [         R                  R                  S5      [         R
                  R                  SS	S
S	SS9[         R                  R                  SSSSSSSS9[         R
                  R                  SSSSSS9[         R                  R                  SSSS9[         R                  R                  SSSSS9/[        R                  SS9/S 9$ )!Nr   )rs   r0   ru   rv   rw   zRun MoGe Inferencez:Run MoGe on a single image to estimate depth and geometry.rx   ry   rz   r|   r}   r   z0 = fastest, 9 = most detail.r~   fov_x_degreesr3   g     @e@g?TzHorizontal field of view of the source camera. Sets the focal length used to unproject the depth map into 3D. 0 = auto-recover from the predicted points.)r   r   r   stepadvancedr{   r   r   r   @   zHImages per inference call. Lower if you OOM on a long video / image set.r   )r   r   r   zSet masked-out (sky / invalid) pixels to inf in points and depth so meshing culls them. Disable to keep the raw predicted geometry everywhere; the mask is still returned separately.)r   r   r{   r   r   rL   r   rM   r   rN   rO   rP   )
r   rQ   rV   rS   r   r   FloatBooleanr   rW   rX   s    r-   rZ   MoGeInference.define_schema   s   yy#c-T0##L1w'/q%D  F%VYdh (C  D\1!%o  q

  !3TD Q

  td *a ! b "((o(FG'
 	
r/   r   c                   ^ USS S24   nUR                  SS5      R                  5       nUR                  S   n	US::  a  S O
[        U5      n
[        R
                  R                  U	5      n/ m[        U	SS9 n[        SX5       Hd  nXX-    nTR                  UR                  XU
XgS95        UR                  [        X-   U	5      5        UR                  UR                  S   5        Mf     S S S 5        U4S	 jnS
UR                  5       0nS H  nU" U5      nUc  M  UUU'   M     [        R                   " U5      $ ! , (       d  f       NW= f)N.r   r   r   r   zMoGe inferencer   )r|   r   r   r   c                    > T Vs/ s H  oU;   d  M
  X   PM     nnU(       a  [         R                  " USS9$ S $ s  snf )Nr   r   )r   cat)fieldcvalschunkss      r-   stack$MoGeInference.execute.<locals>.stack   s<    &,;f
HAHfD;-1599Tq);t; <s   	;;rz   )r   r0   r   r   normal)r   
contiguousr5   r   r_   r`   r   r   r4   r   r   r   r   r   r   r   rb   )rY   ry   rz   r|   r   r   r   r   bchwBfovr   r   r;   chunkr  r   r   vr   s                      @r-   re   MoGeInference.execute   s>    c2A2g}}R$//1JJqM#q(deM.B{{&&q) 01R1a,q~.j..u_b@P / i j$$S%;<		%++a.) - 2	< !%))+.HEeA}'(e$ I }}]++# 21s   8A5D>>
Erg   Nrh   rg   r/   r-   r   r      s>    
 
. ,vx  wD  wD , ,r/   r   c                   T    \ rS rSrSr\S 5       r\S\R                  4S j5       r	Sr
g)
MoGeRenderi  z;Render a visualization or mask from a MOGE_GEOMETRY packet.c                     [         R                  " S/ SQSSS[        R                  S5      [         R                  R                  S/ SQS	S
S9/[         R
                  R                  5       /S9$ )Nr  )rs   renderru   r0   r  zRender MoGe Geometryz3Render a depth map or normal map from geometry datarx   r   output)r0   depth_colorednormal_openglnormal_directxr   r0   zDirectX vs OpenGL controls the normal-map green-channel convention. DirectX: green = -Y down (Unreal). OpenGL: green = +Y up (Blender, Substance, Unity, glTF).)rK   r   r{   r   )r   rQ   r   rS   rR   r   rW   rX   s    r-   rZ   MoGeRender.define_schema  sp    yy L/M0""?3x1v  AH ~  
 XX__&'
 	
r/   r   c                 ~   US;   nUR                  S5      nUS;   a  SU;  a  [        S5      eUS   nOUU(       a#  SU;   a  US   nOBSU;   a  US   nO6[        S5      eUS	:X  a  S	U;  a  [        S
5      eUS	   nO[        SU 35      eUR                  S   n[        R                  R                  U5      n/ n[        USU 3S9 n	[        U5       GH^  n
XZU
S-    R                  5       nUS;   ag  [        U5      nUR                  US:X  a  [        U5      O:UR                  S5      R                  " / UR                  QSP76 R                  5       5        OU(       a\  SU;   a  UO
[        U5      nU(       a  SOSnXR!                  SUS/5      -  nUR                  US-  S-   R#                  SS5      5        OPUS	:X  aJ  UR                  UR                  S5      R                  " / UR                  QSP76 R                  5       5        UR%                  U
S-   5        U	R'                  S5        GMa     S S S 5        [(        R*                  " USS9R-                  [        R.                  R1                  5       [        R.                  R3                  5       S9n[4        R6                  " U5      $ ! , (       d  f       N= f)N)r  r  _opengl)r0   r  r0   z"moge_geometry has no depth output.r  r   zDmoge_geometry has neither normals nor points to derive normals from.r   z!moge_geometry has no mask output.zUnknown output mode: r   zMoGe render: r   r   r  r   r         r2   g      ?r3   r   r   )endswithr   r5   r_   r`   r   r   r4   r   rD   r   _turbor    expandr  r.   
new_tensorr9   r   r   r   r   r   r   intermediate_deviceintermediate_dtyper   rb   )rY   r   r  	is_normalopenglsrcr  r   r:   r   r;   slcr<   r,   y_signr   s                   r-   re   MoGeRender.execute  s   AA	+ //m+ !EFF(C=(#H-]*#H- !ghhv]* !DEE'C4VH=>>IIaL{{&&q)"$-x 89R1XAEl((*77,S1AJJFo,Evay$%KKO$:$:$GAGG$GQ$G$R$R$TV'=8>RSV>WA%+TFLL#vt)<==AJJC#44S#>?v%JJs}}R077FFAFQQST$$QU+		!  :" 3A&))1G1G1[1[1]eje{e{  fO  fO  fQ)  R}}V$$% :9s   E/J..
J<rg   Nr   rg   r/   r-   r  r    s6    E
 
 ,%r}} ,% ,%r/   r  c                   T    \ rS rSrSr\S 5       r\S\R                  4S j5       r	Sr
g)MoGePointMapToMeshiK  zLTriangulate one image of a MoGe point map into a Types.MESH (UVs + texture).c                    [         R                  " S/ SQSSS[        R                  S5      [         R                  R                  SSSS	S
S9[         R                  R                  SSSSSS9[         R
                  R                  SSSSSSS9[         R                  R                  SSSS9/[         R                  R                  5       /S9$ )Nr$  )rs   meshru   z	point mapzConvert MoGe Point Map to Meshz(Convert a MoGe point map into a 3D mesh.rx   r   batch_indexr   i   zWhich image of a batched MoGe geometry to mesh. Per-image vertex counts differ, so batches can't be stacked into a single MESH.r~   
decimationr      z#Vertex stride; 1 = full resolution.discontinuity_thresholdg{Gz?r3   r2   g{Gz?z@Drop pixels whose 3x3 depth span exceeds this fraction. 0 = off.)r   r   r   r   r{   textureTz8Carry the source image through as the baseColor texture.)r   r{   r   )	r   rQ   r   rS   r   r   r   MeshrW   rX   s    r-   rZ    MoGePointMapToMesh.define_schemaN  s    yy(D9B0""?3]A1$&_  ` \1!%J  L8$CUX_c'i  k

  D)c ! e WW^^%&%
 	
r/   r   c                    SU;  a  [        S5      eUS   nUR                  S   nX':  a  [        SU SU S35      eSU;   a  US   U   OS n[        Xb   UXHS9u  pnU	R                  S   S:X  d  U
R                  S   S:X  a  [        S	5      eS
U;  a  U	S S 2/ SQ4   R                  5       n	O=U	[        R
                  " / SQU	R                  S9-  n	U
S S 2/ SQ4   R                  5       n
U(       a
  US   X"S-    OS n[        R                  " U	R                  S5      U
R                  S5      UR                  S5      US9n[        R                  " U5      $ )Nr   z#moge_geometry has no points output.r   zbatch_index z, out of range; moge_geometry has batch size .r0   )r(  r*  r0   zOMoGe produced an empty mesh; try discontinuity_threshold=0 or apply_mask=False.r   )r   r   r   )r2   r  r  )r   )r   r   r   rz   r   )verticesfacesuvsr+  )r   r5   r	   r  r   tensorr   r   MESHr    r   rb   )rY   r   r'  r(  r*  r+  r   r  
edge_depthvertsr1  r2  texr&  s                 r-   re   MoGePointMapToMesh.executee  sd   =(BCCx(LLO|K=8defdgghijj =D}<T]7+K8Z^
1J$;
c ;;q>Q%++a.A"5noo},!Y,'224E ELL):%++NNE!Y,'224EELmG$[qARVzz__Q'//!$a 	
 }}T""r/   rg   Nr   rg   r/   r-   r$  r$  K  s9    V
 
, !#bdbobo !# !#r/   r$  c                   L    \ rS rSr\S\\\R                        4S j5       r	Sr
g)MoGeExtensioni  r   c                 @   #    [         [        [        [        [        /$ 7fN)rF   r   rp   r  r$  )selfs    r-   get_node_listMoGeExtension.get_node_list  s     }.CZQcdds   rg   N)ri   rj   rk   rl   r   r   typer   	ComfyNoder>  rn   rg   r/   r-   r:  r:    s,    eT$r||*<%= e er/   r:  c                     #    [        5       $ 7fr<  )r:  rg   r/   r-   comfy_entrypointrC    s     ?s   ))r   r   comfy.utilsr_   rT   comfy_api.latestr   r   r   typing_extensionsr   comfy.ldm.colormapr   r  comfy.ldm.moge.modelr   comfy.ldm.moge.geometryr	   comfy.ldm.moge.panoramar
   r   r   r   r   comfy.model_management	tqdm.autor   CustomrV   r   Tensorr.   rD   rA  rF   rp   r   r  r$  r:  rC  rg   r/   r-   <module>rO     s    T    6 6 & . * 9 K  K  		,'yy)E E%,, E  $,BLL ,({,BLL {,|4,BLL 4,n@% @%F<# <#~eN e r/   