You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
4.6 KiB
127 lines
4.6 KiB
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 did<len(cd):
|
|
d=cd[did]
|
|
bx=int(d['x']+10); by=int(d['y']-6)
|
|
ch_top=root.op(f'lbl_ch_{i}'); en_top=root.op(f'lbl_en_{i}')
|
|
cx=bx
|
|
if ch_top:
|
|
ch_arr=ch_top.numpyArray(delayed=False)
|
|
if ch_arr is not None: cx=_blit_top(img,ch_arr,cx,by,ca,H)
|
|
if en_top:
|
|
en_arr=en_top.numpyArray(delayed=False)
|
|
if en_arr is not None: _blit_top(img,en_arr,cx+4,by,ca,H)
|
|
|
|
# 4. Ellipse dots
|
|
if ast in (_EXPAND,_ELLIPSE):
|
|
ei=int(ea*255)
|
|
for d in cd:
|
|
x,y=d['x'],d['y']
|
|
draw.ellipse([x-ds,y-ds,x+ds,y+ds],fill=(255,255,255,ei))
|
|
|
|
# 5. Ellipse outline
|
|
if ast==_ELLIPSE and edt>0:
|
|
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)
|
|
|