
    
3jG                       S SK r S SKJr  S SKrS SKJrJrJrJr  S SK	r
SSKJrJr  S SKrS SKrS SKJr  S rS rS	 r " S
 S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      r " S  S!5      r  " S" S#5      r! " S$ S%5      r" " S& S'5      r# " S( S)5      r$ " S* S+5      r% " S, S-5      r& " S. S/5      r' " S0 S15      r(g)2    N)
transforms)Image	ImageDraw	ImageFontImageFilter   )
pil2tensor
tensor2pil)BytesIOc                 ~    [        U [        5      (       a'  SU ;   a!  [        S U R                  S5       5       5      $ U $ )N,c              3   T   #    U  H  n[        UR                  5       5      v   M      g 7fN)intstrip).0cs     N/home/wildlama/comfy/ComfyUI/custom_nodes/ComfyUI-KJNodes/nodes/curve_nodes.py	<genexpr>parse_color.<locals>.<genexpr>   s     >-=S^^-=s   &()
isinstancestrtuplesplitcolors    r   parse_colorr      s4    %#,>U[[-=>>>L    c                    / n [        U [        5      (       a8  [        R                  " U R	                  SS5      5      nUR                  U5        O@U  H:  n[        R                  " UR	                  SS5      5      nUR                  U5        M<     U(       a&  [        US   [        5      (       a  SUS   ;   a  U/nU$ U(       aL  [        US   [        5      (       a4  US   (       a*  [        US   S   [        5      (       a  SUS   S   ;   a   U$ [        S[        US   5       35         U$ ! [        R                   a  n[        SU 35        / n S nAU$ S nAff = f)N'"r   xz"Warning: Unexpected track format: zError parsing tracks JSON: )r   r   jsonloadsreplaceextendappenddictlistprinttypeJSONDecodeError)trackstracks_dataparsed	track_stres        r   parse_json_tracksr2      sn   Kfc""ZZsC 89Fv& $	I$5$5c3$?@""6* $
 :k!nd;;{ST~@U&-K  ZA==+a.U_`klm`nop`qswUxUx  ~A  EP  QR  ES  TU  EV  ~V  6tKN7K6LMN 	  +A3/0	s%   B8D. >AD. D. .EEEc                    SS K nUR                  S5        SSKJn  Sn	Sn
XR                  R
                  S'   UR                  R                  US-  US-  4SS9u  pUR                  R                  U
5        UR                  U
5        UR                  U	S	S
S9  UR                  SU	S9  UR                  SU	S9  UR                  5       UR                  5       -    H  nUR                  U	5        M     UR                  SU-   5        UR                  S5        UR                  S5        UR!                  SU5        UR#                  US5        UR                  R%                  SSSSSSS9  UR                  R'                  S5      n/ nU" U5      nUR)                  5       UR+                  5       -  u  p![-        [/        X5      5       GHb  u  nu  u  nnnU[1        U 5      S-
  -  nU" U5      nUU-  nUU-  nUR2                  R5                  UUS-  -
  UUS-  -
  4UUSUSS
S9nUR7                  U5        U[1        U 5      S-
  :  a4  U U   u  nnU US-      u  nnUR9                  SUU4UU4[;        SS	SUSS9S 9  UR=                  5          [>        R@                  " URC                  5       S!S"9RE                  [G        U5      [G        U5      S#5      RI                  5       n[N        RP                  " U5      RS                  5       S&-  nURU                  S5      nURW                  U5        GMe     UR                  RY                  U5        [N        RZ                  " USS'9n U $ ! [J         aW    [>        R@                  " URM                  5       S!S"9RE                  [G        U5      [G        U5      S$5      nUS S 2S S 2/ S%Q4   n Nf = f)(Nr   Agg)FigureCanvasAggz#999999z#353535z
text.colord   )figsizedpi-      ?)r   	linestyle	linewidthr"   r   yzposition for: zX CoordinatezY Coordinateg{Gz?gffffff?g?g?)leftrightbottomtopwspacehspacerainbow   r   none)r<   	edgecolor	facecoloralpha z->   )
arrowstyler;   lwr   mutation_scale)xyxytext
arrowpropsuint8dtype      )rE   r   rU   g     o@dim).
matplotlibusematplotlib.backends.backend_aggr5   pyplotrcParamssubplotspatchset_facecolorgrid
set_xlabel
set_ylabelget_xticklabelsget_yticklabels	set_color	set_titleset_xlimset_ylimsubplots_adjustget_cmapget_size_inchesget_dpi	enumerateziplenpatches	Rectangle	add_patchannotater(   drawnp
frombuffertostring_rgbreshaper   copyAttributeErrortostring_argbtorch
from_numpyfloat	unsqueezer'   closecat)!coordinatesheightwidthbbox_height
bbox_widthsize_multiplierpromptrY   FigureCanvas
text_colorbg_colorfigaxtextcmapimage_batchcanvasir"   r=   sizecolor_indexr   draw_height
draw_widthrectx1y1x2y2image_npimage_tensorimage_batch_tensors!                                    r   plot_coordinates_to_tensorr   /   s   uS
3=""<0##,,eCi5LRU,V		)
"
jC3?
c,
c,&&(2+=+=+??DNN:& @
%./
n%
n%
Au
FA))t4RV_bkn)o  )))4c"++-=!*3{+L!MA~As;/!34K%E%,K#d*J%%//Z\1A1{ST}CT0UWacn675TZbe 0 gDLL 3{#a''$QB$QU+BBB8RH'+t69/027;=	(?  @ KKM5==)<)<)>gNVVWZ[aWbdghmdnpqrwwy !++H5;;=EL'11!4L|,7 "N: 	$"YY{:!! " 5==)=)=)?wOWWX[\bXcehineoqrs#Aq)O45s   AMAO ?O c                   F    \ rS rSr\S 5       rSrSrSrSr	Sr
S/4S	 jrS
rg)PlotCoordinatesn   c                 t    SSS04SSSS.4SSS	S
S	S.4SSS	S
S	S.4SSS	S
S	S.4SSS	S
S	S.4S.SSS/SS.40S.$ )NSTRING
forceInputTtitleFdefault	multilineINT         r   minmaxstep   )r   r   r   r   r   r   r   FLOAT      ?r   r   requiredoptional ss    r   INPUT_TYPESPlotCoordinates.INPUT_TYPESo   s     /7t8L-M'/WSX1Y&Z(-3qQU_`/a'b).CRV`a0b(c-2AVZde4f,g.3QW[ef5g-h /se[_:`0ab	 		r   )IMAGEr   r   r   r   )imagesr   r   r   r   r'   KJNodes/experimentalz>
Plots coordinates to sequence of images using Matplotlib.  

r   c           	      D   [         R                  " UR                  SS5      5      nU Vs/ s H  oS   US   4PM     nn[        U5      n	U(       a  [        U5      U	:w  a  S/U	-  nO"Xy[        U5      -  -  US U	[        U5      -   -   n[	        XX6XWU5      n
XXEU4$ s  snf )Nr    r!   r"   r=   r   )r#   r$   r%   rp   r   )selfr   r   r   r   r   r   r   coord
batch_sizeplot_image_tensors              r   r'   PlotCoordinates.append   s    jj!4!4S#!>?=HI[Ec
E#J/[I%
#o"6*"D cJ.O-s??S1STWf  hJhrux  zI  vJ  iJ  XK  KO6{E`j  ~B  C!&kJJ Js   Br   N__name__
__module____qualname____firstlineno__classmethodr   RETURN_TYPESRETURN_NAMESFUNCTIONCATEGORYDESCRIPTIONr'   __static_attributes__r   r   r   r   r   n   sA    
 
 :LNLH%HK
 be`e Kr   r   c                   D    \ rS rSr\S 5       rSrSrSrSr	Sr
 SS	 jrS
rg)SplineEditor   c                     SSSS.4SSSS.4SSSSSS	.4SSSSSS	.4SS
SSSS	.4/ SQSS04/ SQSS04SSSSSS	.4SSSSSS	.4/ SQSS04S.
SSSSSS	.4SSSSSS	.4SS.S.$ ) Nr   FTr   advancedr   r   r   r   r      r   i  rE   )pathtimecontrolpointsspeedr   r   )	cardinalmonotonebasislinearzstep-beforez
step-afterpolarzpolar-reversebezierr   r   r:           r   {Gz?)r)   pandas seriestensorr)   )
points_storer   
mask_widthmask_heightpoints_to_samplesampling_methodinterpolationtensionrepeat_outputfloat_output_typeg     g     @r   )	min_value	max_valuebg_imager   r   clss    r   r   SplineEditor.INPUT_TYPES   s     "*D+Q R (4*PQ$#aVW&XY %3qWX'YZ%*1T[\,]$^ v	$
 :" $SVZ%[\"'QqWX)Y!Z v&C*X &3xPWae'fg%3xPWae'fg'Y1
 1	
r   )MASKr   r   r   r   )mask	coord_strr   countnormalized_str
splinedataKJNodes/weightsa  
# WORK IN PROGRESS  
Do not count on this as part of your workflow yet,  
probably contains lots of bugs and stability is not  
guaranteed!!  
  
## Graphical editor to create values for various   
## schedules and/or mask batches.  

**Shift + click** to add control point at end.
**Ctrl + click** to add control point (subdivide) between two points.  
**Right click on a point** to delete it.    
Note that you can't delete from start/end.  
  
Right click on canvas for context menu:  
NEW!:
- Add new spline
    - Creates a new spline on same canvas, currently these paths are only outputed  
      as coordinates.
- Add single point
    - Creates a single point that only returns it's current position coords  
- Delete spline
    - Deletes the currently selected spline, you can select a spline by clicking on   
    it's path, or cycle through them with the 'Next spline' -option.  

These are purely visual options, doesn't affect the output:  
 - Toggle handles visibility
 - Display sample points: display the points to be returned.  

**points_to_sample** value sets the number of samples  
returned from the **drawn spline itself**, this is independent from the  
actual control points, so the interpolation type matters.  
sampling_method: 
 - time: samples along the time axis, used for schedules  
 - path: samples along the path itself, useful for coordinates  
 - controlpoints: samples only the control points themselves  

output types:
 - mask batch  
        example compatible nodes: anything that takes masks  
 - list of floats
        example compatible nodes: IPAdapter weights  
 - pandas series
        example compatible nodes: anything that takes Fizz'  
        nodes Batch Value Schedule  
 - torch tensor  
        example compatible nodes: unknown
Nc                 D  ^^ [         R                  " U5      n/ n/ n[        U[        5      (       a*  [	        U5      S:  a  [        US   [        5      (       a  UnOU/nU(       a  US   O/ nU H  n/ n/ nU H  n[        [        US   5      5      US'   [        [        US   5      5      US'   SUS   T-  -
  S-
  X-
  -  U-   nSUS   T-  -
  S-
  X-
  -  U-   nUR                  U5        UR                  UUS.5        M     UR                  U5        UR                  U5        M     US:X  a  X-  nOKUS:X  a   SS K	nUR                  X-  5      4nO+US
:X  a%  [        R                  " X-  [        R                  S9nUU4S jnW(       a  UOU/nU Vs/ s H  nU" U5      PM     nn[        R                  " U5      nUR!                  U
SSS5      nUR#                  SS9n[	        U5      n UcC  U[         R$                  " [	        U5      S:  a  UOUS   5      WU [         R$                  " U5      4$ [&        R(                  " 5       n!U!" US   R+                  SSS5      5      n"[-        5       n#U"R/                  U#SSS9  U#R1                  5       n$[2        R4                  " U$5      R7                  S5      n%SU%/0U[         R$                  " [	        U5      S:  a  UOUS   5      WU [         R$                  " U5      4S.$ ! [         a  n[        S	5      UeS nAff = fs  snf )Nr   r"   r=   r   r   r"   r=   r)   r   [MaskOrImageToWeight: pandas is not installed. Please install pandas to use this output_typer   rS   c                 R   > [         R                  " TTS4U [         R                  S9$ )NrU   rS   )r}   fullfloat32)r=   r   r   s    r   <lambda>)SplineEditor.splinedata.<locals>.<lambda>-  s     ejj+z1)EqPUP]P]^r   rE   rW   r   JPEGK   formatqualityutf-8r   uiresult)r#   r$   r   r)   rp   r   roundr'   r&   pandasImportErrorSeriesr}   r   r  stackrepeatmeandumpsr   
ToPILImagepermuter   savegetvaluebase64	b64encodedecode)&r   r   r   r   r   r   r   r   r   r   r   r   r   r   all_normalizedall_normalized_y_valuescoordinate_setsfirst_spline	coord_set
normalizednormalized_y_valuesr   norm_xnorm_y
out_floatspdr1   	color_mapy_values_for_masksr=   mask_tensors	masks_outsingle_spline_count	transformimagebuffered	img_bytes
img_base64s&    ``                                   r   r   SplineEditor.splinedata   s~    jj- "$ k4((S-=-AjQ\]^Q_aeFfFf)O  +mO-<q)" )IJ"$" uSz!23c
 uSz!23c
sk!9:S@YEZ[^ggsk!9:S@YEZ[^gg#**62!!v6":; # !!*-#**+>? )  &0@J/1H# #:#JKLJ(*&=&MUZUbUbcJ^	4G0i[.@A.@	!.@AKK-	$$]Aq!<	NNrN*	!,/tzz[9IA9M+S^_`Sabdn  qD  FJ  FP  FP  Q_  F`  a  a"--/Ihqk11!Q:;EyHJJxJ; !))+I)))4;;GDJ "J<0$djjK@PST@TZefgZh&iku  xK  MQ  MW  MW  Xf  Mg  h 7  H!"  A  GH  HH Bs   <K? L?
L	LLr   )r   r   N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s?    2
 2
h ALMLH H/Kf 7;Hr   r   c                   J    \ rS rSrSrSrSrSrSrSr	\
S 5       rS	/4S
 jrSrg)CreateShapeMaskOnPathiH  )r   r   )r   mask_invertedcreateshapemaskKJNodes/masking/generatez`
Creates a mask or batch of masks with the specified shape.  
Locations are center locations.  
Tc                 v    / SQSS04SSS04SSS	S
SS.4SSS	S
SS.4SSSS
SS.4SSSS
SS.4S.SSS/SS.40S.$ )Ncirclesquaretriangler   r>  r   r   Tr   r   r   r   rE   r   r   r   )shaper   frame_widthframe_heightshape_widthshape_heightr   r   r   r   r   r   r   s    r   r   !CreateShapeMaskOnPath.INPUT_TYPEST  s    

 x !)<*>? %3bWX'YZ!&Cr$XY(Z [ %3aVW'XY!&CqWX(Y Z
  cU$)OP
! 	r   r   c                    UR                  SS5      n[        R                  " U5      n[        U5      n/ n	Sn
U(       a  [        U5      U:w  a  S/U-  nO"Xx[        U5      -  -  US U[        U5      -   -   n[	        U5       GH1  u  p[
        R                  " SX#4S5      n[        R                  " U5      n[        SXKX{   -  -   5      n[        SX[X{   -  -   5      nUS   nUS   nUS	:X  d  US
:X  aR  UUS-  -
  UUS-  -
  4nUUS-  -   UUS-  -   4nUU/nUS	:X  a  UR                  UU
S9  OZUS
:X  a  UR                  UU
S9  OCUS:X  a=  UUS-  -
  UUS-  -   4nUUS-  -   UUS-  -   4nUUUS-  -
  4nUR                  UUU/U
S9  [        U5      nUS S 2S S 2S S 2S4   nU	R                  U5        GM4     [        R                   " U	SS9nUSU-
  4$ )Nr    r!   whiter   RGBblackr"   r=   r>  r?  r   fillr@  rW   r   )r%   r#   r$   rp   rn   r   newr   Drawr   ellipse	rectanglepolygonr	   r'   r}   r   )r   r   rB  rC  rD  rE  rA  r   r   outr   r   r   r2  ru   current_widthcurrent_height
location_x
location_yleft_up_pointright_down_point
two_points	top_pointr   outstacks                            r   r:  %CreateShapeMaskOnPath.createshapemaskk  sU   !))#s3jj-%
#o"6*"D cJ.O-s??S1STWf  hJhrux  zI  vJ  iJ  XK  KO!+.HAIIek%@'JE>>%(D  ;_5G1G#GHM L7I3I$IJNsJsJ EX$5!+mq.@!@*~abObBb c$.!1C$CZR`deReEe#f +-=>
H$LL%L8h&NN:EN:*$!+mq.@!@*~abObBb c$.!1C$CZR`deReEe#f 'n6I)IJ	i8HIPUVu%EAq!$DJJt? /@ 99Sa(#.**r   r   N)r   r   r   r   r   r   r   r   r   
DEPRECATEDr   r   r:  r   r   r   r   r8  r8  H  sE    $L-L H)HK J , z}x} -+r   r8  c                   L    \ rS rSrSrSrSrSrSr\	S 5       r
S/SS	S
4S jrSrg)CreateShapeImageOnPathi  r   r   r2  r   r:  KJNodes/imagezc
Creates an image or batch of images with the specified shape.  
Locations are center locations.  
c                     / SQSS04SSS04SSS	S
SS.4SSS	S
SS.4SSSS
SS.4SSSS
SS.4SSS04SSS04SSSSSS.4SSSSSS.4S.
SS/SS.4SSSSSS.4SSSSSS.4SSS04S.S.$ )Nr=  r   r>  r   r   Tr   r   r   r   rE   r   r   r   rH  rJ  r   r   r6   g?r   r         Y@)
rA  r   rB  rC  rD  rE  shape_colorr   blur_radius	intensityr   g      $@r   )r   trailingborder_widthborder_colorr   r   r   s    r   r   "CreateShapeImageOnPath.INPUT_TYPES  s   

 x !)<*>? %3bWX'YZ!&Cr$XY(Z [ %3aVW'XY!&CqWX(Y Z (9g*>?%	7';< 'SSZ])^_%3tE[_'`a#
( !(cU$)OP c#dTX"YZ"!CQR$ST%	7';<	
) 	r   r   r   rJ  c           	      |   [        U5      n[        U5      n[        U5      n[        U5      n[        US   5      n/ n/ nU(       a  [        U5      U:w  a  S/U-  nO#UU[        U5      -  -  US U[        U5      -   -   nS n[        U5       GH  n[        R
                  " SX#4U5      n[        R                  " U5      nXKU   -  nX[U   -  nU GH	  nUU   S   nUU   S   nU	S:X  d  U	S:X  a  UUS-  -
  UUS-  -
  4nUUS-  -   UUS-  -   4nUU/nU	S:X  a+  US:  a  UR                  UXnUS	9  Mc  UR                  UUS
9  Mu  U	S:X  a+  US:  a  UR                  UXnUS	9  M  UR                  UUS
9  M  M  U	S:X  d  M  UUS-  -
  UUS-  -   4nUUS-  -   UUS-  -   4nUUUS-  -
  4nUS:  a  UR                  UUU/XnUS	9  M  UR                  UUU/US
9  GM     US:w  a%  UR                  [        R                  " U5      5      n[        U5      nUS:w  a  Ub  UUU-  -  nUUR                  5       -  nUnUU
-  nUS S 2S S 2S S 2S4   n UR!                  U 5        UR!                  U5        GM     ["        R$                  " USS9R'                  5       R)                  5       n!["        R$                  " USS9n"U!U"4$ )Nr   rE   rI  r"   r=   r>  r?  r   )rL  outliner   rK  r@  r   rW   )r   r2   rp   ranger   rM  r   rN  rO  rP  rQ  filterr   GaussianBlurr	   r   r'   r}   r   cpur   )#r   r   rB  rC  rD  rE  re  r   rf  rA  rg  r   rh  ri  rj  coords_listr   images_list
masks_listprevious_outputr   r2  ru   rS  rT  coordsrU  rV  rW  rX  rY  rZ  r   
out_images	out_maskss#                                      r   r:  &CreateShapeImageOnPath.createshapemask  s^    "+."<0x('4Q(

#o"6*"D cJ.O-s??S1STWf  hJhrux  zI  vJ  iJ  XK  KOz"AIIek%@(KE>>%(D (!*<<M)A,>>N%#AYs^
#AYs^
H$(9%/-12D%DjSaefSfFf$gM(2]a5G(GVdhiViIi'j$"/1A!BJ('!+ LL+coLp LL+LF(*'!+ NN:KeqNr NN:KNH	 + j(%/-12D%DjSaefSfFf$gM(2]a5G(GVdhiViIi'j$!+Z.A:M-M NI#a'i@P%QXc  BN  Oi@P%QXcd= &@ a!LL)A)A+)NOE u%E3?#>O33		+#OI%EAq!$Dd#u%k #l YY{2668>>@
IIja0	I&&r   r   N)r   r   r   r   r   r   r   r   r   r   r   r:  r   r   r   r   r_  r_    sN    %L%L HHK
  < SVQVadst  DKK'r   r_  c                   F    \ rS rSrSrSrSrSrSr\	S 5       r
S/4S	 jrS
rg)CreateTextOnPathi  )r   r   r   )r2  r   r9  createtextmaskr;  z_
Creates a mask or batch of masks with the specified text.  
Locations are center locations.  
c           
          SSS04SSSS.4SSSS	S
S.4SSSS	S
S.4[         R                  " S5      4SSS04/ SQSS04SSS04S.SSS/SS.40S.$ )Nr   r   Tr   r   r   r   r   r   rE   r   kjnodes_fontsr   *   )r>   centerr?   r  rH  )r   r   rB  rC  font	font_size	alignmentr   r   r   r   r   r   folder_pathsget_filename_listr   s    r   r   CreateTextOnPath.INPUT_TYPES  s     !)<*>?!vD#IJ %3bWX'YZ!&Cr$XY(Z [%77HK#i_5 H%  ()W)=>
" cU$)OP
# 	r   r   c
           
      f   UR                  SS5      n[        R                  " U5      n[        U5      n
/ n/ n[	        U5      n[
        R                  " SU5      n[        U	5      U
:w  a"  X[        U	5      -  -  U	S U
[        U	5      -   -   n	[        U5       GH  u  nn[        R                  " SX#4S5      n[        R                  " U5      nUR                  S5      n[        XYU   -  5      n[        R                  " UU5      nU Vs/ s H  nUR!                  U5      S   PM     nn[#        U5      nUS   US	-  -
  n[        U5       H  u  nnUR!                  U5      S	   UU   nnUS
:X  a  US   nO2US:X  a  [        US   US	-  -
  5      nOUS:X  a  [        US   U-
  5      n[        U[#        US U 5      -   5      nWU4n UR%                  UUUUS/S9  M     [)        U5      nUS:  R+                  SS9n U R-                  UR.                  5      n!UR1                  U!5        UR1                  U5        GM     [2        R4                  " USS9R7                  5       R9                  5       n"[2        R4                  " USS9n#U"U#SU#-
  4$ s  snf ! [&         a    UR%                  UUUUS9   GMf  f = f)Nr    r!   r~  rI  rJ  
rU   r=   r   r>   r"   r  r?   z-liga)rL  r  featuresrL  r  r   r  rW   r   )r%   r#   r$   rp   r   r  get_full_pathrn   r   rM  r   rN  r   r   r   truetypegetbboxsumr   	Exceptionr	   anytorT   r'   r}   r   rq  r   )$r   r   rB  rC  r  r  r   r   r  r   r   	mask_list
image_listr   	font_pathr   r   r2  ru   linescurrent_font_sizecurrent_fontlineline_heightstotal_text_heightstart_yj
text_widthtext_heightrU  rV  text_positionnon_black_pixelsr   rw  rx  s$                                       r   r|  CreateTextOnPath.createtextmask5  s   !))#s3jj-%
	
J' ..E	:--s??S1STWf  hJhrux  zI  vJ  iJ  XK  KO!+.HAuIIek%@'JE>>%(DJJt$E #I0B$B C$--i9JKLFKLedL006q9eLL #L 1 Cj#4#99G$U+4*6*>*>t*DQ*GVWK
&!&sJ(*!$U3Z*/%A!BJ')!$U3Z*%<!=J 3|BQ/?+@!@A
!+Z 8RIImTL\c[dIe ," u%E %	26#&&u{{3DT"e$C /F YYzq1557==?
IIiQ/	IsY88= M& ! RIImTLIQRs   J
JJ0/J0r   N)r   r   r   r   r   r   r   r   r   r   r   r|  r   r   r   r   r{  r{    sD    -L6LH)HK
  . EH  DI 29r   r{  c                   >    \ rS rSrSrSrSrSrSr\	S 5       r
S rS	rg
)CreateGradientFromCoordsii  r   r2  generaterb  z0
Creates a gradient image from coordinates.    
c                 Z    SSSS04SSSSS	S
.4SSSSS	S
.4SSS04SSS04SSSSSS
.4S.0$ )Nr   r   r   Tr   r   r   r   rE   r   r   rH  rJ  r   r   r   rd  )r   rB  rC  start_color	end_color
multiplierr   r   s    r   r   $CreateGradientFromCoords.INPUT_TYPESs  ss      (<*>? %3bWX'YZ!&Cr$XY(Z [ (9g*>?&G(<=&CU\`(ab
	 		r   c           
         [         R                  " UR                  SS5      5      n[        R                  " SX#45      n[
        R                  " U5      nUS   n	US   n
[        U5      n[        U5      nU
S   U	S   -
  U
S   U	S   -
  4nUS   S-  US   S-  -   S	-  n[        U5       H  n[        U5       H  nXS   -
  XS   -
  4nUS   US   -  US   US   -  -   U-  n[        [        UU5      S5      nUU-  U-  n[        US   US   US   -
  U-  -   5      [        US   US   US   -
  U-  -   5      [        US   US   US   -
  U-  -   5      4nUR                  X4US
9  M     M     [        U5      nU4$ )Nr    r!   rI  r   rE   r"   r=   r   r:   rK  )r#   r$   r%   r   rM  r   rN  r   rn  r   r   r   pointr	   )r   r   rB  rC  r  r  r  r2  ru   start_coord	end_coordgradient_directiongradient_lengthr=   r"   point_vector
projectionblendr   r   s                       r   r  !CreateGradientFromCoords.generate  s   jj!4!4S#!>? 		%+!<=~~e$ "!nN	!+.	*	 (n{3/??3R]^aRbAbc-a0A58J18MQR8RRWZZ |$A;' !$4 4ac:J6JK*1o0B10EEUVZlmnZoHoo  tC  C
 Z!A1E
 #Z//A A)A,Q*G5)PPQA)A,Q*G5)PPQA)A,Q*G5)PPQ 

A6
.# ( %* "%(r   r   N)r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r  r  i  s6    LLHHK 
 
+r   r  c                   >    \ rS rSrSrSrSrSrSr\	S 5       r
S rS	rg
)GradientToFloati  )r   r   )float_xfloat_ysamplerb  z+
Calculates list of floats from image.    
c                     SSSSSSSS.4S	.0$ )
Nr   r   r   
   r   i'  rE   r   )r2  stepsr   r   s    r   r   GradientToFloat.INPUT_TYPES  s+     $R%QR!ST
 	r   c                 f   UR                   u  p4pV[        R                  " SUS-
  U[        R                  S9nUSS S 2US4   n[        R                  " SUS-
  U[        R                  S9n	USU	S S 2S4   n
UR	                  SS9R                  5       nU
R	                  SS9R                  5       nX4$ )Nr   rE   )r  rT   rW   )rA  r}   linspaceint64r  tolist)r   r2  r  BHWCw_intervals	w_sampledh_intervals	h_sampledw_valuesh_valuess                r   r  GradientToFloat.sample  s    [[
a nnQAU%++N!QQ./	 nnQAU%++N![!Q./	 >>a>(//1>>a>(//1##r   r   N)r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r  r    s6    &L+LHHK  $r   r  c                   >    \ rS rSr\S 5       rSrSrSrSr	S
S jr
S	rg)MaskOrImageToWeighti  c                 "    S/ SQSS040SSS.S.$ )	Noutput_type)r)   r   r   stringr   r)   r   r   )r   masksr   r   r   s    r   r   MaskOrImageToWeight.INPUT_TYPES  s9      6	  %"
 	
r   )r   r   executer   zb
Gets the mean values from mask or image batch  
and returns that as the selected output type.   
Nc                 @   / nUb:  Uc7  U H0  nUR                  UR                  5       R                  5       5        M2     ONUc:  Ub7  U H0  nUR                  UR                  5       R                  5       5        M2     OUb  Ub  [        S5      eUS:X  a  UnOHUS:X  a   SS KnUR                  U5      4nO*US:X  a$  [        R                  " U[        R                  S94nWU V
s/ s H  n
[        U
5      PM     sn
4$ ! [
         a  n	[        S5      U	eS n	A	ff = fs  sn
f )Nz9MaskOrImageToWeight: Use either mask or image input only.r)   r   r   r  r   rS   )r'   r  item
ValueErrorr  r  r  r}   r   r  r   )r   r  r   r  mean_valuesr   r2  rR  r+  r1   values              r   r  MaskOrImageToWeight.execute  s!   ""499;#3#3#56 ]v1""5::<#4#4#67  6#5XYY & CO+H# ))K()CH$,,{%--@ACk:kUc%jk:<<  H!"  A  GH  HH
 ;s   C= $D=
DDDr   )NNr   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r  r    s1    
 
( (LH HK
=r   r  c                   J    \ rS rSr\S 5       rSrSrSrSr	S r
SS	 jrS
 rSrg)WeightScheduleConverti  c                     SSSS.4/ SQSS04SSS	04S
SSSSS.4S.S
SS04SSS04SSS	04SSSSSS.4SSSSSS.4S.S.$ )Nr   r   Tr   match_inputr)   r   r   r   r)   BOOLEANFr   rE      r   )input_valuesr  invertr  r   r   i`yg     j@r   r   )remap_to_framesinterpolation_curveremap_values	remap_min	remap_maxr   r   r   s    r   r   !WeightScheduleConvert.INPUT_TYPES  s     ")c*N O 6	  %y%&89 aqa"PQ  %*Iq>#:(/,1E'F!*Y,> ?%3wxae'fg%3wxae'fg!
 	
r   )r   r   r   r  r   z:
Converts different value lists/series to another type.  
c                     SS K n[        U[        5      (       a  g[        XR                  5      (       a  g[        U[        R
                  5      (       a  g[        S5      eNr   r)   r   r   zUnsupported input typer  r   r)   r  r}   Tensorr  r   r  r+  s      r   detect_input_type'WeightScheduleConvert.detect_input_type/  G    lD))ii00"ell33566r   Nc
                 T   SS K n
U R                  U5      nUS:X  a  UR                  5       nOUS:X  a  UnOUnU(       a  U Vs/ s H  nSU-
  PM
     nnUb  / nUnU H  n[        U5      n[	        U5      nU Vs/ s H  oU-
  UU-
  -  PM     nn[
        R                  " [
        R                  " SS[        UW-  5      5      [
        R                  " SS[        U5      5      U5      R                  5       nUR                  U5        M     UnOUS:  a  U[        U5      :w  a  [        U5      n[	        U5      nU Vs/ s H  oU-
  UU-
  -  PM     nn[
        R                  " [
        R                  " SSU5      [
        R                  " SS[        U5      5      U5      R                  5       nX-  nU	(       a  U R                  XU5      nUS:X  a  U4nOUS:X  a  U
R                  U5      4nOiUS:X  aZ  US:X  a/  [        R                  " UR                  [        R                   S94nO.[        R                  " U[        R                   S94nO	US:X  a  U4nWU Vs/ s H  n[#        U5      PM     snU Vs/ s H  n[        U5      PM     sn4$ s  snf s  snf s  snf s  snf s  snf )Nr   r   r   rE   r)   rS   r  )r  r  r  r   r   rv   interpr  r   rp   r&   r  r  r}   r   valuesr  r   )r   r  r  r  r  r  r  r  r  r  r+  
input_typefloat_valuesr  interpolated_patternorig_float_valuesmin_valmax_valnormalized_valuesremapped_float_valuesrR  s                        r   r  WeightScheduleConvert.execute:  s   ++L9
('..0L8#'L'L3?@<%AI<L@*#%  ,,/0/0Zk$lZkQVgo'G:K%LZk!$l(*		"++aCZ_H_D`2acecncnoprsux  zK  vL  dM  O`  )a  )h  )h  )j%$++,AB - 0L "#l:K'Kl+l+Zf$gZfQVgo'G:K%LZf!$g!yyQ?)KR[[YZ\]_bct_uMv  yJ   K   R   R   T'0L#00)T& -CO+))L)*CH$_,ll<#6#6emmLMll<u}}EFM)-Cl;lUc%jl;Vb=cVbUc%jVb=cddO A %m %h& <=cs   J:J>JJ 8J%c                     [        U5      n[        U5      nXT-
  nX2-
  nU Vs/ s H  oU-
  U-  U-  U-   PM     n	nU	$ s  snf r   )r   r   )
r   r  
target_min
target_maxcurrent_mincurrent_maxcurrent_rangetarget_ranger  remapped_valuess
             r   r  "WeightScheduleConvert.remap_valueso  s`    &k&k#1 ". kqqjpafK/=@<OR\\jpq rs   >r   )r   Nr   r   F)r   r   r   r   r   r   r   r   r   r   r  r  r  r   r   r   r   r  r    s=    
 
4 /LH HK	73ejr   r  c                   :    \ rS rSr\S 5       rSrSrSrSr	S r
Srg	)
FloatToMaski~  c                 0    SSSSS.4SSSS	.4SSSS	.4S
.0$ )Nr   r   Tr   )r   r   r   r6   rE   )r   r   )r  r   r   r   r   s    r   r   FloatToMask.INPUT_TYPES  s=     !(!*L MS!;< c!"<=
 	
r   r  r  r;  z
Generates a batch of masks based on the input float values.
The batch size is determined by the length of the input float values.
Each mask is generated with the specified width and height.
c                    SS K n[        U[        [        45      (       a  U/nOs[        XR                  5      (       a  UR                  5       nOH[        U[        5      (       a3  [        S U 5       5      (       a  U VVs/ s H  oU  H  ofPM     M     nnn/ nU H;  n[        R                  " X24[        R                  S9U-  n	UR                  U	5        M=     [        R                  " USS9n
U
4$ s  snnf )Nr   c              3   B   #    U  H  n[        U[        5      v   M     g 7fr   )r   r)   )r   r  s     r   r   &FloatToMask.execute.<locals>.<genexpr>  s     3dWctJtT4J4JWc   rS   rW   )r  r   r   r   r  r  r)   allr}   onesr  r'   r  )r   r  r   r   r+  sublistr  r  r  r   r/  s              r   r  FloatToMask.execute  s    lUCL11(>Lii00'..0Ld++3dWc3d0d0d0<QWDDLQ !E::voU]]CeKDLL " KK1-	l Rs    C2r   Nr  r   r   r   r  r  ~  s1    
 
 LH)HKr   r  c                   @    \ rS rSr\S 5       rSrSrSrSr	S r
S rS	rg
)WeightScheduleExtendi  c                 2    SSSSS.4SSSS.4/ SQSS04S	.0$ )
Nr   r   r   Tr   r  r   r  )input_values_1input_values_2r  r   r   s    r   r    WeightScheduleExtend.INPUT_TYPES  sF     #*4,P"Q#*4,P"Q =	 
 	
r   r   r  r   zA
Extends, and converts if needed, different value lists/series  
c                     SS K n[        U[        5      (       a  g[        XR                  5      (       a  g[        U[        R
                  5      (       a  g[        S5      er  r  r  s      r   r  &WeightScheduleExtend.detect_input_type  r  r   c                 B   SS K nU R                  U5      nU R                  U5      nXV:X  dM  [        S5        US:X  a  UR                  U5      nO7US:X  a#  [        R
                  " U[        R                  S9nO[        S5        UnUW-   nUS:X  a  U4$ US:X  a  UR                  U5      4$ US:X  aX  US:X  a.  [        R
                  " UR                  [        R                  S94$ [        R
                  " U[        R                  S94$ US:X  a  U4$ [        S	U 35      e)
Nr   z>Converting input_values_2 to the same format as input_values_1r   r   rS   z'Input types match, no conversion neededr)   r  zUnsupported output_type: )	r  r  r*   r  r}   r   r  r  r  )	r   r  r  r  r+  input_type_1input_type_2float_values_2r  s	            r   r  WeightScheduleExtend.execute  s   --n=--n=+RS.!#>!:)!&nEMM!R;<+N%6& = O+99\*++H$.||L$7$7u}}MNN||LFGGM)= 8FGGr   r   N)r   r   r   r   r   r   r   r   r   r   r  r  r   r   r   r   r  r    s7    
 
$ LH HK	7 Hr   r  c                   >    \ rS rSr\S 5       rSrSrSrSr	Sr
S rSrg	)
FloatToSigmasi  c                     SSSSSS.400$ )Nr   
float_listr   r   Tr   r   r   s    r   r   FloatToSigmas.INPUT_TYPES  s#    !GD-Q#R 	r   SIGMASKJNodes/noisecustomsigmasz7
Creates a sigmas tensor from list of float values.  

c                 J    [         R                  " U[         R                  S94$ )NrS   )r}   r   r  )r   r'  s     r   r,  FloatToSigmas.customsigmas  s    ||Jemm<==r   r   Nr   r   r   r   r   r   r   r   r   r   r   r,  r   r   r   r   r%  r%    s6      LLHHK>r   r%  c                   >    \ rS rSr\S 5       rSrSrSrSr	Sr
S rS	rg
)SigmasToFloati  c                     SSS00$ )Nr   sigmasr)  r   r   s    r   r   SigmasToFloat.INPUT_TYPES  s    { 	r   r  )r   r+  r,  z.
Creates a float list from sigmas tensors.  

c                 $    UR                  5       4$ r   )r  )r   r3  s     r   r,  SigmasToFloat.customsigmas  s    }}r   r   Nr/  r   r   r   r1  r1    s6      LLHHK r   r1  c                   F    \ rS rSr\S 5       rSrSrSrSr	Sr
S/4S	 jrS
rg)GLIGENTextBoxApplyBatchCoordsi  c                 Z    SSSSSSS04SSS04S	S
SSSS.4S	S
SSSS.4S.SSS/SS.40S.$ )N)CONDITIONING)LATENT)CLIP)GLIGENr   r   Tr   r   r   r   r   r   )conditioning_tolatentsclipgligen_textbox_modelr   r   r   r   r   r   r   r   r   r   r   s    r   r   )GLIGENTextBoxApplyBatchCoords.INPUT_TYPES  st    0B)5&06B.6t8L-M'/+t1D&E(-3qQU_`/a'b).CRV`a0b(c /se[_:`0ab
 
	r   )r:  r   )conditioningcoord_previewr'   r   a  
This node allows scheduling GLIGEN text box positions in a batch,  
to be used with AnimateDiff-Evolved. Intended to pair with the  
Spline Editor -node.  

GLIGEN model can be downloaded through the Manage's "Install Models" menu.  
Or directly from here:  
https://huggingface.co/comfyanonymous/GLIGEN_pruned_safetensors/tree/main  
  
Inputs:  
- **latents** input is used to calculate batch size  
- **clip** is your standard text encoder, use same as for the main prompt  
- **gligen_textbox_model** connects to GLIGEN Loader  
- **coordinates** takes a json string of points, directly compatible  
with the spline editor node.
- **text** is the part of the prompt to set position for  
- **width** and **height** are the size of the GLIGEN bounding box  
  
Outputs:
- **conditioning** goes between to clip text encode and the sampler  
- **coord_preview** is an optional preview of the coordinates and  
bounding boxes.

r   c
           	      v   [         R                  " UR                  SS5      5      nU V
s/ s H  oS   U
S   4PM     nn
[        S UR	                  5        5       5      n[        U5      U:w  a  [        S5        / nUR                  UR                  U5      SS9u  pU GHE  nUS	   US
   R                  5       /n[        U5       Vs/ s H  n/ PM     nn[        U	5      U:w  a"  X[        U	5      -  -  U	S U[        U	5      -   -   n	[        U5       H\  nUU   u  nnU[        US-  U	U   -  5      [        US-  U	U   -  5      UUS-  -
  S-  UUS-  -
  S-  4nUU   R                  U5        M^     / nSUS
   ;   a  US
   S   S   nO[        U5       Vs/ s H  n/ PM     nn[        UU5       VVs/ s H  u  nnUU-   PM     nnnSUU4US
   S'   UR                  U5        GMH     US   R                  S   S-  nUS   R                  S   S-  n[        UUUXX5      nUU4$ s  sn
f s  snf s  snf s  snnf )Nr    r!   r"   r=   c              3   B   #    U  H  oR                  S 5      v   M     g7f)r   N)r   )r   r   s     r   r   7GLIGENTextBoxApplyBatchCoords.append.<locals>.<genexpr>C  s     G6FFQ6Fr  zeGLIGENTextBoxApplyBatchCoords WARNING: The number of coordinates does not match the number of latentsT)return_pooledr   rE   r   r   gligenposition_batchedsamplesr  )r#   r$   r%   r  r  rp   r*   encode_from_tokenstokenizerz   rn  r   r'   ro   rA  r   )r   r?  r   r>  r@  rA  r   r   r   r   r   r   r   _cond_pooledtnposition_params_batchr   
x_position
y_positionposition_paramprev	prev_item
batch_itemcombined_position_paramsimage_heightimage_widthr   s                                r   r'   $GLIGENTextBoxApplyBatchCoords.append?  s   jj!4!4S#!>?=HI[Ec
E#J/[IGgnn6FGG
{z)yz00t1DTX0Y A1qtyy{#A16z1B$C1BAR1B!$C?#z1"13CW5W"X[j  lNlvy|  ~M  zN  mN  \O  #O:&)4Q&
J"-sFaK?STCU3U/VX[]bfg]gkz{|k}\}X~  BL  OU  YZ  OZ  BZ  _`  A`  cm  pu  yz  pz  cz  @  b@  "A%a(//? '
 D1Q4tH~a($)*$56$5q$56 ]``df{\|'}\|CX9j	J(>\|$'}02FH`aAaDNHHQK+ !. y)//3a7i(..r2Q66{LR]_en}  E$&&I J %D 7 (~s   H&H+H03H5r   Nr   r   r   r   r8  r8    sD      /L6LH%HK2 B  ~C &'r   r8  c                   H    \ rS rSrSrSrSrSrSr\	S 5       r
S/S	4S
 jrSrg)CreateInstanceDiffusionTrackingig  )TRACKINGr   r   r   r   r   )trackingr   r   r   r   r   ra  KJNodes/InstanceDiffusionz
Creates tracking data to be used with InstanceDiffusion:  
https://github.com/logtd/ComfyUI-InstanceDiffusion  
  
InstanceDiffusion prompt format:  
"class_id.class_name": "prompt",  
for example:  
"1.head": "((head))",  
c                     SSS04SSSSSS	.4SSSSSS	.4SSSSSS	.4SSSSSS	.4SS
S04SSSSSS	.4SSSS.4S.SS/SS.4SS
S04S.S.$ )Nr   r   Tr   r   r   r   rE   r   r   
class_namer   r  r   r   )r   r   r   r   r   rd  class_idr   r   r   r   r  )r   fit_in_framer   r   r   s    r   r   +CreateInstanceDiffusionTracking.INPUT_TYPESw  s     !)<*>?S4QR!ST cDRS"TU$#RVW&XY %3bWX'YZ')\)BC"3PQ$RS#%MN	
 !(cU$)OP&D(9:
 	r   r   Tc           
      d   UR                  SS5      n[        R                  " U5      n0 n0 X'   [        U5      n/ nU	(       a  [        U	5      U:w  a  S/U-  n	O"X[        U	5      -  -  U	S U[        U	5      -   -   n	[	        U5       H  u  pUS   nUS   nXiU   -  nXyU   -  nUUS-  -
  nUUS-  -
  nUUS-  -   nUUS-  -   nU
(       aX  [        SU5      n[        SU5      n[        UU5      n[        UU5      n[        SUU-
  5      n[        SUU-
  5      nUU-   nUU-   nUR                  UUUUXE/5        M     [        U5      nXU   U'   SnUR                  5        H7  u  nnUR                  5        H  n[        U5      nUSU S	U S
U S3-  nM     M9     UR                  S5      nUUXEXg4$ )Nr    r!   r   r"   r=   r   rE   rJ   .z": "(z)",
z,
)r%   r#   r$   rp   rn   r   r   r'   r   itemskeysr   rstrip)r   r   rd  re  r   r   r   r   r   r   rf  trackedr   id_coordinatesr   r   r"   r=   adjusted_bbox_widthadjusted_bbox_height
top_left_x
top_left_ybottom_right_xbottom_right_yprompt_string
class_dataclass_id_strs                              r   ra  (CreateInstanceDiffusionTracking.tracking  s3   !))#s3jj- %
#o"6*"D cJ.O-s??S1STWf  hJhrux  zI  vJ  iJ  XK  KO!+.HAc
Ac
A",q/A"A#.1C#C 0A55J1Q66J!4!99N!5!::N J/
 J/
!$UN!;!$V^!<&)!^j-H&I#'*1nz.I'J$ ",.A!A!+.B!B !!:z>>[`"ij5 /8 x=(6
H%&-mmo"J
&OO-"8}1\N!J<uVHE!RR . '6 &,,U3zOOr   r   N)r   r   r   r   r   r   r   r   r   r   r   ra  r   r   r   r   r_  r_  g  sH    FLZLH*HK  $ |z  OS 8Pr   r_  c                   B    \ rS rSrSrSrSrSrSr\	S 5       r
SS jrS	rg
)AppendInstanceDiffusionTrackingi  )r`  r   )ra  r   r'   rb  zr
Appends tracking data to be used with InstanceDiffusion:  
https://github.com/logtd/ComfyUI-InstanceDiffusion  

c                 <    SSS04SSS04S.SSSS.4SSSS.4S.S	.$ )
Nr`  r   T)
tracking_1
tracking_2r   rJ   r   )prompt_1prompt_2r   r   r   s    r   r   +AppendInstanceDiffusionTracking.INPUT_TYPES  sN      *L$+?@)L$+?@

 "r#FG!r#FG
	 		r   c                     UR                  5       nUR                  5        H#  u  pgXe;  a  XuU'   M  XV   R                  U5        M%     US-   U-   nXX4$ )Nr   )rz   rj  update)	r   r|  r}  r~  r  tracking_copyrd  rv  ru  s	            r   r'   &AppendInstanceDiffusionTracking.append  s^    ")&0&6&6&8"J.,6j) )00< '9 !31--r   r   N)rJ   rJ   )r   r   r   r   r   r   r   r   r   r   r   r'   r   r   r   r   rz  rz    s6    *L*LH*HK 
 
.r   rz  c                   >    \ rS rSrSrSrSrSrSr\	S 5       r
S rS	rg
)InterpolateCoordsi  )r   )r   interpolater   z/
Interpolates coordinates based on a curve.   
c                      SSSS04SSS04S.0$ )Nr   r   r   Tr   )r   r  r   r   s    r   r   InterpolateCoords.INPUT_TYPES  s0      (<*>?(/,1E'F
 	r   c                   ^ [         R                  " TR                  SS5      5      mT Vs/ s H  o3S   US   4PM     snm[        U4S j[	        S[        T5      5       5       5      n/ nSnSnU GHj  nX-  n	U[        T5      S-
  :  a{  [        R                  " TU   5      [        R                  " TUS-      5      p[        R                  R                  X-
  5      nXl-   U	:  a  OXl-  nUS-  nU[        T5      S-
  :  a  M{  U[        T5      S-
  :  a  [        R                  " TU   5      [        R                  " TUS-      5      p[        R                  R                  X-
  5      nUS:  a2  X-
  U-  nXX-
  -  -   nUR                  UR                  5       5        GM4  UR                  UR                  5       5        GMV  UR                  TS   5        GMm     S	S
R                  U Vs/ s H$  nS[        US   5       S[        US   5       S3PM&     sn5      -   S-   n[        U5        U4$ s  snf s  snf )Nr    r!   r"   r=   c           	   3      >#    U  HX  n[         R                  R                  [         R                  " TU   5      [         R                  " TUS -
     5      -
  5      v   MZ     g7f)rE   N)rv   linalgnormarray)r   r   r   s     r   r   0InterpolateCoords.interpolate.<locals>.<genexpr>  sO      =!;A ))..+a.)ABHH[YZ[\Y\M]D^)^__!;s   A A#rE   r   r  [z, z{'x': z, 'y': }])r#   r$   r%   r  rn  rp   rv   r  r  r  r'   r  joinr  r*   )r   r   r  r   path_lengthinterpolated_coordscurrent_lengthcurrent_indexnormalized_lengthtarget_lengthsegment_startsegment_endsegment_lengthp1p2rQ  interpolated_pointinterpolated_coords_strs    `                r   r  InterpolateCoords.interpolate  s`   jj!4!4S#!>? >II[Ec
E#J/[I  =!&q#k*:!;= = ! "5-;M#k"2Q"66-/XXk-6P-QSUS[S[\ghuxyhy\zS{{!#0K!L!2mC0"  #k"2Q"66 s;/!33+m"<=rxxTadeTeHf?gB!#!8!A%&7>IA)+27m);&'../A/H/H/JK'..ryy{; $**;r?;- "52 #&		  wJ  3K  wJmrWU58_<MWUZ[`ab[cUdTeeg3h  wJ  3K  )L  #L  OR  #R%&'))Q JJ 3Ks   H61+H;
r   N)r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r  r    s6    L#LH%HK  -*r   r  c                   >    \ rS rSrSrSrSrSrSr\	S 5       r
S rS	rg
)DrawInstanceDiffusionTrackingi-  r   r  ru   rb  zH
Draws the tracking data from  
CreateInstanceDiffusionTracking -node.

c           	      h    SSSSS04SSSS	SS
.4SSS04[         R                  " S5      4SSS04S.0$ )Nr   r   r`  r   Tr   r   rE   r  r   r  r   r~  rK   )r2  ra  box_line_width	draw_textr  r  r  r   s    r   r   )DrawInstanceDiffusionTracking.INPUT_TYPES9  sb     $',)=>#(a"VW*X"Y')T):;%77HK#i_5
	 		r   c                    SS K Jn  / nUR                  S[        U5      5      n	U(       a-  [        R
                  " SU5      n
[        R                  " X5      n[        UR                  S   5       GH  nXS S 2S S 2S S 24   R                  SSS5      n[        R                  " 5       " U5      n[        R                  " U5      n[        UR!                  5       5       GH#  u  nu  nnUR!                  5        GH  u  nnU[        U5      :  d  M  UU   n[#        U[$        [&        45      (       a  Uu  nnnn  n[)        U5      [)        U5      [)        U5      [)        U5      4u  nnnn['        S U	" U[        U5      -  5       5       5      S S nUR+                  UUUU/UUS9  U(       a8  U S	U 3nUR-                  S
UUS9u    nnnUUU-
  4nUR/                  UUUUS9  M  M  [1        S[3        U5       35        GM     GM&     [        R4                  " 5       " U5      R                  SSS5      nUR7                  U5        GM     [8        R:                  " U5      R=                  5       R?                  5       n U 4$ )Nr   rD   r~  r   rE   c              3   >   #    U  H  n[        S U-  5      v   M     g7f)r  N)r   )r   r"   s     r   r   5DrawInstanceDiffusionTracking.draw.<locals>.<genexpr>d  s     )\@[1#cAg,,@[s   rU   )rm  r   ri  )r   r   )r   r  r  zUnexpected data type for bbox: ) matplotlib.cmcmrk   rp   r  r  r   r  rn  rA  r  r   r  r   rN  rn   rj  r   r)   r   r   rP  textbboxr   r*   r+   ToTensorr'   r}   r  rq  r   )!r   r2  ra  r  r  r  r  r  modified_imagescolormapr  r   current_image	pil_imageru   r  rd  rv  re  	bbox_listbboxr   r   r   r   rO  r   r   r  r  r  modified_image_tensorimage_tensor_batchs!                                    r   ru   "DrawInstanceDiffusionTracking.drawF  sN   ";;y#h-8$22?DII%%i;D u{{1~&A!Q1*-55aA>M"--/>I>>),D 099I/J++J
+5+;+;+='Hi3y>)(|%dT5M::370BBAq-0Wc"gs2wB-ONBB$))\SQY]IZ@[)\$\]_^_$`E NNBB+;UR`Na(*21ZL'A@Df[_fj@k =1j+13R+5E0F $		-EPT	 U  ) "$CDJ<"PQ- ,> 0K4 %/$7$7$9)$D$L$LQPQST$U!""#89G 'L #[[9==?EEG!""r   r   N)r   r   r   r   r   r   r   r   r   r   r   ru   r   r   r   r   r  r  -  s6    LLH*HK 
 
3#r   r  c                   B    \ rS rSr\S 5       rSrSrSrSr	Sr
SS	 jrS
rg)PointsEditori{  c                     SSSS.4SSSSS.4SSSSS.4SSSS.4SSSSS.4SS/4SS	S
SS
S.4SS	S
SS
S.4SSS04S.	SS0S.$ )Nr   FTr   )r   
socketlessr   xyxyxywhr   r   r   r   r   r  r   )	r   r   neg_coordinates
bbox_storebboxesbbox_formatr   r   	normalizer   r   r   r   r   s    r   r   PointsEditor.INPUT_TYPES|  s     "*D+Q R (T_c*de$,EQUcg.h#i'u$)OP#5Z^%_`    S4QR!ST c!DRS"TU')U);<" K#
 	
r   )r   r   BBOXr   r   )positive_coordsnegative_coordsr  	bbox_maskcropped_image	pointdatar   a  
# WORK IN PROGRESS
Do not count on this as part of your workflow yet,
probably contains lots of bugs and stability is not
guaranteed!!

## Graphical editor to create coordinates

**Shift + click** to add a positive (green) point.
**Shift + right click** to add a negative (red) point.
**Right click on a point** to delete it.
**Ctrl + click** to draw a bounding box.
**Drag bbox corners** to resize, **drag inside** to move.
**Right click on bbox** to delete it.

To add an image select the node and copy/paste or drag in the image.
Or from the bg_image input on queue (first frame of the batch).

**THE IMAGE IS SAVED TO THE NODE AND WORKFLOW METADATA**
you can clear the image from the context menu by right clicking on the canvas

Nc                    [         R                  " U5      nU(       d  [        S5      e/ nU H}  n[        [	        US   5      5      US'   [        [	        US   5      5      US'   U(       a%  US   U-  nUS   U-  nUR                  XS.5        Mc  UR                  US   US   S.5        M     U(       a  [         R                  " U5      n/ nU H}  n[        [	        US   5      5      US'   [        [	        US   5      5      US'   U(       a%  US   U-  nUS   U-  nUR                  XS.5        Mc  UR                  US   US   S.5        M     [        R                  " XC4[        R                  S9n[         R                  " U5      n/ nU GHb  nUR                  S5      b6  UR                  S5      b$  UR                  S5      b  UR                  S	5      c  MN  [        [        US   5      [        US   5      5      n[        [        US   5      [        US	   5      5      n[        [        US   5      [        US   5      5      n[        [        US   5      [        US	   5      5      nUR                  UUUU45        / nU H*  nUu  nnnnUR                  UUUU45        S
UUU2UU24'   M,     U	S:X  a5  / nU H(  nUu  nnnnUU-
  nUU-
  nUR                  UUX445        M*     UnGM`  UnGMe     [        R                  " U5      nUR                  S5      R                  5       R!                  5       nU
b+  [#        U5      S:  a  US   u  nnnnU
S S 2UU2UU2S S 24   nO+U
b  U
nO%[        R                  " S
XCS[        R$                  S9nU
c/  [         R&                  " U5      [         R&                  " U5      UUU4$ [(        R*                  " 5       nU" U
S   R-                  SSS
5      5      n[/        5       nUR1                  USSS9  [2        R4                  " UR7                  5       5      R9                  S5      nSU/0[         R&                  " U5      [         R&                  " U5      UUU4S.$ )Nz}No points on the canvas. Use Shift+click to add positive points or Shift+right-click to add negative points before executing.r"   r=   r  rS   startXstartYendXendYrE   r  r   rU   r   r	  r
  r  r  r   r  )r#   r$   r  r   r  r'   rv   zerosrR   getr   r   r}   r~   r   r   rq  rp   r  r  r   r  r  r   r  r  r  r  r   )r   r   r  r   r   r   r  r  r  r  r   pos_coordinatesr   r(  r)  r   valid_bboxesr  x_miny_minx_maxy_maxbboxes_xyxybboxes_xywhmask_tensorr  r1  r2  r3  r5  s                                 r   r  PointsEditor.pointdata  sX   jj-  ]  ^  ^ EU5:./E#JU5:./E#Jse+sf,&&V'AB&&U3ZeCj'IJ ! **_5K O$ uSz!23c
 uSz!23c
"3Z%/F"3Z&0F#**+EF#**s%*+MN % xxrxx8F#D"*"* ( ( CX/T&\1BCCX/T&\1BCCX/T&\1BCCX/T&\1BC##UE5%$@AK$-1*ueU""E5%#?@12U5[%+-. %
 f$ (D15.E5%!EME"U]F&&ue'DE	 )
 %$= @ &&t,!++A.446::<C$5$9)/&E5%$QeU5[!%CDM!$M!KK6!5==QMJJ/O1LfVacpqq"--/Ihqk11!Q:;EyHJJxJ;))(*;*;*=>EEgNJ "J<0::o6

?8SU[]hjwx r   r   )r  N)r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r  r  {  s8    
 
. AL_LH%HK.Wr   r  c                   B    \ rS rSrSrSrSrSrSr\	S 5       r
SS	 jrS
rg)CutAndDragOnPathi  r`  ra  
cutanddragrb  z
Cuts the masked area from the image, and drags it along the path. If inpaint is enabled, and no bg_image is provided, the cut area is filled using cv2 TELEA algorithm.
c           
      J    SSSS04SSSSS	S
S.4SSSS	S
S.4SSS04S.SS0S.$ )Nr   r   r   Tr  r   r   r   r   rE   r   r  r   )r2  r   r   rB  rC  inpaintr   r   r   r   s    r   r   CutAndDragOnPath.INPUT_TYPES  sc     $ (<*>?! %3bWX'YZ!&Cr$XY(Z [%	4'89
 

 	r   Nc                    [        U5      n[        US   5      n	/ n
/ n[        U5      S   n[        U5      S   n[        R                  " U5      n[        R
                  " US:  5      u  nn[        U5      S:X  d  [        U5      S:X  a  X4$ UR                  5       UR                  5       nnUR                  5       UR                  5       nnUU-
  nUU-
  nUR                  UUUU45      nUR                  UUUU45      nUc  UR                  5       nU(       a  SS K
nSn[        R                  " SUR                  S5      n[        R                  " U5      nUR!                  UU-
  UU-
  UU-   UU-   /SS9  UR#                  [        R                  " U5      [        R                  " U5      SUR$                  S9n[        R&                  " U5      nO[        U5      S   n[)        U	5       H  nUR                  5       n[        R                  " SXE4S5      n U HZ  n![+        U!U   S   US	-  -
  5      n"[+        U!U   S
   US	-  -
  5      n#UR-                  UU"U#4U5        U R-                  UU"U#45        M\     [/        U5      n$[/        U 5      n%U
R1                  U$5        UR1                  U%5        M     [2        R4                  " U
SS9R7                  5       R9                  5       n&[2        R4                  " USS9n'U&U'4$ )Nr      Lr  rK  rU   )inpaintRadiusflagsr"   r   r=   rW   )r2   rp   r
   rv   r  wherer   r   croprz   cv2r   rM  r   r   rN  rP  r  INPAINT_TELEA	fromarrayrn  r   paster	   r'   r}   r   rq  r   )(r   r2  r   r   rB  rC  r  r   rr  r   rs  rt  input_image
input_mask
mask_array	y_indices	x_indicesr  r  r  r  	cut_width
cut_height	cut_imagecut_mask
backgroundr  border	fill_maskru   r   	new_imagenew_maskrv  target_xtarget_yr   r  rw  rx  s(                                           r   r  CutAndDragOnPath.cutanddrag!  s   '4Q(

 !'*%a(
 XXj)
!xx
Q7	9y>Q#i.A"5=  }}	u }}	u EM	U]
$$eUE5%AB	??E5%#?@ $))+J!IIc:??A>	 ~~i0feFlE&L%PV,W^ab [[HHZ(HHY'"#++	 ) 
 #__Z8
#H-a0J z"A")Iyy{&A1EH &vay~	!;<vay~
1<= 	Hh+?Jx(H)=> & &i0L$X.K|,k*' #, YY{2668>>@
IIja0	I&&r   r   r   )r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r  r    s7    %L%LHHK  I'r   r  ))r}   torchvisionr   r#   PILr   r   r   r   numpyrv   utility.utilityr	   r
   r  r  ior   r   r2   r   r   r   r8  r_  r{  r  r  r  r  r  r  r%  r1  r8  r_  rz  r  r  r  r  r   r   r   <module>r     s,    "  8 8  4   
<="~!K !KFt tnP+ P+ht' t'lU9 U9nB BH%$ %$N5= 5=np pf& &NGH GHR> >&   &Q' Q'f[P [Pz$. $.LA* A*FL# L#\K KZb' b'r   