
    
3j;2                        S SK r S SKJr  S SKrS SKrS SK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Jr  \R*                  " 5         \" \5      rSSS	.S
 jrS rS rS rS rS rS rSS jrS r " S S5      r \ /r!g)    N)Path)Image   )ModelNotFound)mklog)download_modelget_model_path
tensor2piltiles_infertiles_mergetiles_splitF)	save_tempauto_downloadc                &   U(       a  [        [        R                  " 5       5      OSn[        R                  " U SS SSS9nU(       aK  [
        R                  " US   S-  R                  [        R                  5      5      R                  US-  5        [        R                  SUR                   35        [        R                  S	5        S
nUS-  US-  US-  S.nXxU   -
  n	[        XgU4X45      u  pU(       ac  [        U
5       HT  u  p[
        R                  " US   S-  R                  [        R                  5      5      R                  USU S3-  5        MV     [        R                  S5        [        SS5      nU(       a  UR!                  5       (       d7  U(       d  [#        SU S35      e[        R                  S5        [%        SS5        / SQnU Vs/ s H   nU[&        R(                  " 5       ;   d  M  UPM"     nnU(       d  [+        S5      e[        R                  SU 35        [&        R,                  " UR/                  5       US9n[        R                  S5        [1        U
UUS9nU(       ar  [        U5       Hc  u  nn[
        R                  " UR3                  SSS5      S-  R                  [        R                  5      5      R                  USU S3-  5        Me     [        R                  S 5        [5        UX4SUR                  S   UR                  S   4U5      nU(       aY  [
        R                  " UR3                  SSS5      S-  R                  [        R                  5      5      R                  US!-  5        [7        U5      nU(       aq  [
        R                  " UR3                  SSS5      S-  R                  [        R                  5      5      R                  US"-  5        [        R                  S#U 35        U$ s  snf )$zCompute a normal map from the given color map.

'color_img' must be a numpy array in C,H,W format (with C as RGB).
'overlap' must be one of 'SMALL', 'MEDIUM', 'LARGE'.
N   r   T)axiskeepdims   zgrayscale_img.pngzLConverting color image to grayscale by taking the mean over color channels: u$   DeepBump Color → Normals : tilling         r   SMALLMEDIUMLARGEtile_z.pngu*   DeepBump Color → Normals : loading modeldeepbumpzdeepbump256.onnxz
deepbump ()zDownloading models...z@https://github.com/HugoTini/DeepBump/raw/master/deepbump256.onnx)TensorrtExecutionProviderCUDAExecutionProviderCoreMLProviderCPUExecutionProviderz:No valid ONNX Runtime providers available on this machine.zUsing ONNX providers: )	providersu'   DeepBump Color → Normals : generatingprogress_callback   
pred_tile_u$   DeepBump Color → Normals : mergingzmerged_img.pngzfinal_img.pngzDebug images saved in )r   tempfilemkdtempnpmeanr   	fromarrayastypeuint8savelogdebugshaper   	enumerater	   existsr   r   ortget_available_providersRuntimeErrorInferenceSessionas_posixr   	transposer   	normalize)	color_imgoverlapr%   r   r   temp_dirimg	tile_sizeoverlapsstride_sizetilespaddingsitilemodelr#   provideravailable_providersort_session
pred_tiles	pred_tilepred_imgs                         F/home/wildlama/comfy/ComfyUI/custom_nodes/comfy_mtb/nodes/deep_bump.pycolor_to_normalsrO      s    ,5tH$$&'$H '')BQ-a$
7CQ#--bhh78==**	
 II	)),	5 II45Iaq.aH
 w//K!#k%?OE  'GAOOT!Ws]22288<=BBU1#T?* ( II:;:'9:E*UG1 566		)*N	

I "!Hs2244 	!   H
 	
 II&':&;<=&&$7K
 II78{.?J %j1LAyOO$$Q1-3;;BHHEd8
1#T223 2 II45	"	
CIIaL#))A,'	H 1a(3.66rxx@	

$x**
+ "H1a(3.66rxx@	

$x/)
*		*8*56Ogs   P:Pc                 &   [        U5      nUS-  S:w  d   e[        R                  " XS-  SS9n[        R                  " U R                  5      n[        U R                  S   5       H#  n[        R                  " X5US-  -      USS9XE'   M%     US-  $ )zUPerform row by row 1D convolutions.

of the given 2D image with the given 1D kernel.
r   r   wrap)modevalid)lenr*   pademptyr2   rangeconvolve)array	kernel_1dk_lextendedoutputrE   s         rN   conv_1dr_      s     i.C7a<<vveAXF3HXXekk"F5;;q>"KK#(^$ig
	 #
 B;    c                    [         R                  " U S-
  * S-  U S-
  S-  U 5      n[         R                  " S[         R                  " U5      -  [         R                  " U5      -  5      nU[         R                  " U5      -  $ )z-Return a 1D gaussian kernel of size 'length'.r&   r   g      )r*   linspaceexpsquaresum)lengthsigmaspacekernels       rN   gaussian_kernelrj      se    KK&1*)FQJ!+;VDEVVD299U++bii.>>?FBFF6N""r`   c                     U [         R                  " U 5      -
  [         R                  " U 5      [         R                  " U 5      -
  -  $ )z9Normalize all elements of the given numpy array to [0,1].)r*   minmax)np_arrays    rN   r;   r;      s7    rvvh''
x266(++ r`   c                    Ub	  U" SS5        [         R                  " / SQ5      n[        U SSS2SS24   U5      nUb	  U" SS5        [        SU SSS2SS24   R                  -  U5      R                  nUb	  U" SS5        XE-   nSS	S
SSSSS.nX;  a  [	        U SU 35      e[        [         R                  " U R                  SS 5      Xq   -  5      nUS:  a#  [        U5      n[         R                  " XfU/5      $ US-  S:X  a  US-  nUS-  n	U	S:X  a  Sn	[        X5      n
[        Xj5      nUb	  U" SS5        [        UR                  U
5      R                  nUb	  U" SS5        [        U5      n[         R                  " XU/5      $ )zCompute a curvature map from the given normal map.

'normals_img' must be a numpy array in C,H,W format (with C as RGB).
'blur_radius' must be one of:
    'SMALLEST', 'SMALLER', 'SMALL', 'MEDIUM', 'LARGE', 'LARGER', 'LARGEST'.
Nr   r   )rT   r   r&   r&   rT   r   g      p?g      ?g      ?g      ?g      ?g      ?g      ?SMALLESTSMALLERr   r   r   LARGERLARGESTz not found in r      )r*   rZ   r_   T
ValueErrorintr+   r2   r;   stackrj   )normals_imgblur_radiusr%   diff_kernelh_convv_conv
edges_convblur_factorsblur_radius_pxrg   g_kernelh_blurv_blur	curvatures                 rN   normals_to_curvaturer      s    $!Q((:&K[Aq);7F$!QR+aAg.000+>@@F$!Q J L &K=|nEFF
!!!A&',*CCN
 z*
xx<== Q! aEz~5HZ*F$!QVXXx(**F$!Q &!I 88Y9566r`   c                 .    U S   S-
  S-  U S   S-
  S-  4$ )Nr   g      ?r   r&    )rz   s    rN   normals_to_gradr      s)    NS A%A(<'AAAr`   c                    [         R                  " U [         R                  " U SS9* /5      n[         R                  " [         R                  " U SS9[         R                  " U 5      * /5      n[         R                  " X#/5      n[         R                  " U[         R                  " USS9/5      n[         R                  " [         R                  " USS9* [         R                  " U5      * /5      n[         R                  " XV/5      nXG4$ )zjConcat 4 flipped copies of input gradients (makes them wrap).

Output is twice bigger in both dimensions.
r&   r   r   )r*   hstackflipvstack)grad_xgrad_y
grad_x_topgrad_x_bottom
new_grad_x
grad_y_topgrad_y_bottom
new_grad_ys           rN   	copy_flipr      s    
 FRWWV!%<$<=>JIIrwwvA68HIJMJ67JFBGGF$;<=JIIQ 77"''&/9IJKMJ67J!!r`   c                    Ub	  U" SS5        U R                   u  p4[        R                  " U5      US-  S-   -
  X3S-  -
  -  n[        R                  " U5      US-  S-   -
  XDS-  -
  -  n[        R                  " Xe5      u  px[        R                  R                  U5      n[        R                  R                  U5      nUb	  U" SS5        [        R                  R                  U 5      n	[        R                  R                  U5      n
Ub	  U" SS5        SU-  U	-  SU-  U
-  -   nUS-  US-  -   S-   nX-  nSUS'   [        R                  " [        R                  R                  U5      5      nUb	  U" SS5        U[        R                  " U5      -
  [        R                  " U5      [        R                  " U5      -
  -  $ )	z0Frankot-Chellappa depth-from-gradient algorithm.r   r   r   r&   y             gؗҜ<g        )r   r   )r2   r*   arangemeshgridfft	ifftshiftfft2realifft2rl   rm   )r   r   r%   rowscols
rows_scale
cols_scaleu_gridv_gridgrad_x_Fgrad_y_F	nominatordenominatorZ_FZs                  rN   frankot_chellappar     s~   $!QJD))D/TQY]3axHJ))D/TQY]3axHJ[[8NFVVf%FVVf%F$!Qvv{{6"Hvv{{6"H$!Qv(S6\H-DEI19+e3K

!CCI
S!"A$!Qq	MbffQi"&&)344r`   c                 f   [         R                  " U SS9n[        U5      u  pE[         R                  " USS9n[         R                  " USS9nU(       d  [        XE5      u  pE[	        U* XRS9nU(       d(  U R
                  S   U R
                  S   pUSU2SU24   n[         R                  " XfU/5      $ )zComputes a height map from the given normal map. 'normals_img' must be a numpy array
in C,H,W format (with C as RGB). 'seamless' is a bool that should indicates if 'normals_img'
is seamless.
r&   r   r   r$   r   N)r*   r   r   r   r   r2   ry   )	rz   seamlessr%   flip_imgr   r   rM   heightwidths	            rN   normals_to_heightr   3  s     ww{+H %X.NFWWV!$FWWV!$F "62 !	H
 #))!,k.?.?.BGVGVeVO, 88X233r`   c                   J    \ rS rSrSr\S 5       rSrSrSr	SSSS	S
S.S jr
Srg)MTB_DeepBumpiS  z4Normal & height maps generation from single picturesc                 >    S/ SQ4/ SQ4/ SQ4SSS04S.S	SSS040S
.$ )NIMAGE)Color to NormalsNormals to CurvatureNormals to Heightr   rp   BOOLEANdefaultT)imagerR   color_to_normals_overlap normals_to_curvature_blur_radiusnormals_to_height_seamlessr   )requiredoptionalr   )clss    rN   INPUT_TYPESMTB_DeepBump.INPUT_TYPESV  sX     $ .J,K
5 099d:K.L+0  )i->!?1
 	
r`   r   applyzmtb/texturesr   r   TF)rR   r   r   r   r   c          	         [        U5      n/ nU GH3  n[        R                  SU 35        [        R                  " US5      S-  n	[        R                  SU	R
                   35        S n
US:X  a  [        U	US US9n
US:X  a  [        XS 5      n
US:X  a  [        XS 5      n
U
b  [        R                  S	U
R
                   35        UR                  [        R                  " [        R                  " U
S
5      R                  [        R                  5      5      R                  S5      5        GM  [        R                  S5        GM6     U H%  n[        R                  SUR
                   35        M'     [        R                   " USS94$ )NzInput image shape: )r   r   r&   r   z!transposed for deep image shape: r   )r   r   r   zOutput image shape: )r&   r   r   r   z$No out img... This should not happenzShape fed to utils: )dim)r
   r0   r1   r*   r:   r2   rO   r   r   appendtorch
from_numpyr-   float32	unsqueezeerrorcat)selfr   rR   r   r   r   r   images
out_imagesin_imgout_imgoutis               rN   r   MTB_DeepBump.applyz  sc    E"
EII+E734\\%3c9FII9&,,HIG ))*,"/	 --.d **+ "		0@A!!$$Wi8??

Kil 		@AA B DII,TZZL9: 		*!,..r`   r   N)__name__
__module____qualname____firstlineno____doc__classmethodr   RETURN_TYPESFUNCTIONCATEGORYr   __static_attributes__r   r`   rN   r   r   S  sC    >
 
< LHH  !()0#'0/ 0/r`   r   )N)"r(   pathlibr   numpyr*   r   onnxruntimer5   PILr   errorsr   r0   r   utilsr   r	   r
   r   r   r   disable_telemetry_eventsr   rO   r_   rj   r;   r   r   r   r   r   r   	__nodes__r   r`   rN   <module>r      s          "      Ho sn*#?7FB" #5L4@W/ W/t N	r`   