import numpy as _np import math as _m import sys as _sys #_PIL_PATH = r'C:\Users\user\AppData\Roaming\Python\Python311\site-packages' _PIL_PATH=r'C:\Users\tech\AppData\Local\Programs\Python\Python311\site-packages' _LATIN = 'C:/Windows/Fonts/SpaceMono-Regular.ttf' _CJK = 'C:/Windows/Fonts/NotoSansCJKtc-Regular.otf' _FC = {} _FLOAT=0; _GATHER=1; _LINES=2; _LFADE=3; _EXPAND=4; _ELLIPSE=5 def _font(cjk, sz): from PIL import ImageFont sz=max(8,int(sz)); k=(cjk,sz) if k not in _FC: try: _FC[k]=ImageFont.truetype(_CJK if cjk else _LATIN,sz) except: _FC[k]=ImageFont.load_default() return _FC[k] def _cjk(ch): return '\u4e00'<=ch<='\u9fff' def _blit_top(img, arr, x, y, alpha, H): from PIL import Image as _Img th, tw = arr.shape[:2] arr_f = _np.flipud(arr) lum = arr_f[:,:,0] cols = _np.where(lum.max(axis=0) > 0.05)[0] if len(cols) == 0: return x arr_f = arr_f[:, :int(cols[-1])+1, :] lum_rows = arr_f[:,:,0] row_mask = _np.where(lum_rows.max(axis=1) > 0.05)[0] if len(row_mask) == 0: return x arr_f = arr_f[int(row_mask[0]):int(row_mask[-1])+1, :] th, tw = arr_f.shape[:2] mask_arr = (arr_f[:,:,0] * alpha * 255).clip(0,255).astype(_np.uint8) from PIL import Image as _Img2 mask = _Img2.fromarray(mask_arr, 'L') white = _Img2.new('RGBA', (tw, th), (255,255,255,255)) px=max(0,x); py=max(0, y - th//2) if px >= img.width or py >= img.height: return x + tw cw=min(tw, img.width-px); ch2=min(th, img.height-py) if cw>0 and ch2>0: img.paste(white.crop((0,0,cw,ch2)), (px,py), mask.crop((0,0,cw,ch2))) return x + tw def onSetupParameters(scriptOp): pass def onCook(scriptOp): try: if _PIL_PATH not in _sys.path: _sys.path.insert(0,_PIL_PATH) _do_render(scriptOp) except Exception as e: import traceback; traceback.print_exc() def _do_render(scriptOp): from PIL import Image, ImageDraw root=op('/project1/deep_sound') W=int(root.par.Resw.val); H=int(root.par.Resh.val) st=root.fetch('state_dict',None) or {} ast=int(round(st.get('appState',_FLOAT))) ea=float(st.get('ellipseAlpha',1.)) lfp=float(st.get('labelFadeProgress',0.)) edt=float(st.get('ellipseDrawT',0.)) pids=[int(round(st.get(f'pid{i}',0))) for i in range(4)] ds=max(1.,root.par.Dotsize.val) bg=root.fetch('bg_dots',[]); cd=root.fetch('circle_dots',[]) segs=root.fetch('line_segs',[]); las=root.fetch('label_alphas',[0,0,0,0]) prox=root.fetch('prox_pairs',[]) img=Image.new('RGBA',(W,H),(0,0,0,255)) draw=ImageDraw.Draw(img) # 1. BG lines + dots (floating only) if ast==_FLOAT: for dist,i,j in prox: a=int((1-dist/90)*.6*255) draw.line([(bg[i]['x'],bg[i]['y']),(bg[j]['x'],bg[j]['y'])], fill=(255,255,255,a),width=1) for d in bg: x,y=d['x'],d['y'] draw.ellipse([x-ds,y-ds,x+ds,y+ds],fill=(255,255,255,200)) # 2. Circle dots (not in ellipse states) if ast not in (_EXPAND,_ELLIPSE): for d in cd: x,y=d['x'],d['y'] draw.ellipse([x-ds,y-ds,x+ds,y+ds],fill=(255,255,255,255)) # Connecting lines handled by line_render Script TOP + line_level Level TOP # 3. Line labels (Chinese via lbl_ch_N, English via lbl_en_N) if ast in (_LINES,_LFADE) and pids: fade=1. if ast==_LINES else 1.-lfp for i,did in enumerate(pids): if i>=len(las): break ca=las[i]*fade if ca>0.01 and did0: ei=int(ea*.5*255); n=200; dn=int(n*edt) pts=[(W/2+W*.47*_m.cos(s/n*2*_m.pi-_m.pi/2), H/2+H*.43*_m.sin(s/n*2*_m.pi-_m.pi/2)) for s in range(dn+1)] if len(pts)>1: draw.line(pts,fill=(255,255,255,ei),width=1) arr=_np.ascontiguousarray(_np.flipud(_np.array(img,dtype=_np.float32)/255.)) scriptOp.copyNumpyArray(arr)