main
UC-PC-DEV 2 weeks ago
parent 8a21101b35
commit 96b13df4d0
  1. BIN
      260116-GreyScale.3.toe
  2. BIN
      260308-GrayScale.14.toe
  3. BIN
      260308-GrayScale.6.toe
  4. BIN
      260308-GrayScale.toe
  5. BIN
      260309-GrayScale_standby.1.toe
  6. BIN
      260309-GrayScale_standby.toe
  7. BIN
      Backup/260116-GreyScale.1.toe
  8. BIN
      Backup/260116-GreyScale.2.toe
  9. BIN
      Backup/260308-GrayScale.10.toe
  10. BIN
      Backup/260308-GrayScale.11.toe
  11. BIN
      Backup/260308-GrayScale.12.toe
  12. BIN
      Backup/260308-GrayScale.13.toe
  13. BIN
      Backup/260308-GrayScale.6.toe
  14. BIN
      Backup/260308-GrayScale.7.toe
  15. BIN
      Backup/260308-GrayScale.8.toe
  16. BIN
      Backup/260308-GrayScale.9.toe
  17. 52
      dat_table_json__td_7768_7.tsv
  18. 6
      dat_table_keyword__td_7768_6.tsv
  19. 2
      dat_table_lookat__td_24460_1.tsv
  20. 262
      deep_sound_frame.py
  21. 47
      deep_sound_lines.py
  22. 127
      deep_sound_render.py
  23. 27
      deep_sound_space.py
  24. 48
      deep_sound_text.py
  25. BIN
      osc_points.1.toe

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1 +1,51 @@
text group center_x center_y center_z axis_x axis_y axis_z radius text group center_x center_y center_z axis_x axis_y axis_z radius
大家看不懂 3 0 -0.4123532324273361 0 0 1 0 1.0372877294442566
你哪來的學貸? 0 0 -0.749867176413578 0 0 1 0 0.7548669135932486
介面超難用 2 0 -0.2408329902995598 0 0 1 0 0.4194029232209698
真的嗎 0 0 0.4623510329966389 0 0 1 0 1.5048125315303627
我打開是英文的 2 0 -0.7368388135608597 0 0 1 0 0.8494843186786402
連結: skills.google 3 0 0.139395989566791 0 0 1 0 1.5977131286124318
這肯定不是最近的 0 0 0.3370488241260117 0 0 1 0 1.4914315633910131
幸運的我 接下來就是開始房貸人生 0 0 -0.19097668520390787 0 0 1 0 0.8094034955180638
我買170 0 0 -1.1429481166751554 0 0 1 0 2.0670878753324895
你哪來的學貸? 0 0 -0.6076332826864907 0 0 1 0 0.831596719738272
你到底知不知道外面用人市場 3 0 0.24217833683989254 0 0 1 0 0.6471301997319437
無法同意您更多~ 1 0 -0.6491252211789924 0 0 1 0 0.8838320528906913
邊讀邊還 0 0 0.01362608847808855 0 0 1 0 0.4560166636586928
還沒看懂在討論什麼 1 0 -0.42005793241928235 0 0 1 0 0.6063709493275319
那什麼啦 0 0 -0.9619281018682606 0 0 1 0 1.562724354763271
請問出處 2 0 -1.850633716215873 0 0 1 0 2.5764247392782
你看差多少 0 0 0.06565028895161262 0 0 1 0 1.325940426133994
學貸晚點還沒關係 0 0 0.2527370656563437 0 0 1 0 0.41113186647926575
最近也考慮買一間 0 0 -1.3493273548166158 0 0 1 0 1.7581974612719224
最近貸款通過的朋友 0 0 0.38717201572801146 0 0 1 0 1.2072201654367076
@ariki_fudo66 1 0 -0.15040365289201324 0 0 1 0 0.7017093686995065
商家老闆再次 請慢用 0 0 -0.919191543387093 0 0 1 0 2.289049732331217
來玩ㄇ 0 0 -1.09850381870088 0 0 1 0 2.3271496457556493
哪裡找字幕 1 0 -0.2829123163571337 0 0 1 0 0.9044507454678385
公司幫妳付房貸 0 0 -1.1904257349467433 0 0 1 0 1.4597990188612395
超值! 0 0 -1.2767048888866745 0 0 1 0 2.2807317610058684
可以聊聊唷~ 0 0 0.4291699409620805 0 0 1 0 0.8488469451510265
請問您使用5的couesera 0 0 -0.29592086016284935 0 0 1 0 2.2052729631614167
我貸款也要去租 0 0 -0.8632559828838402 0 0 1 0 1.6100039168811777
別把負債想的太可怕 0 0 -0.6581992846805238 0 0 1 0 0.8823466887149647
附上網頁連結 2 0 -0.23352137567511216 0 0 1 0 0.587397373356631
請各位用低收入戶稱呼 2 0 -1.1677991871458164 0 0 1 0 1.7900899890708353
好辦法 1 0 -0.3040354768710512 0 0 1 0 0.6092131083608139
有保證付多少年嗎 0 0 -0.9288624221613426 0 0 1 0 1.1682449839328297
TOEFL GRE 等級單字 1 0 -1.1760779337182221 0 0 1 0 1.1987248938430015
會考根本不到比天賦 3 0 0.06603930321894402 0 0 1 0 0.4665953643001922
如果隔壁現在開一倍 0 0 -1.3532551932477486 0 0 1 0 1.9823045326399789
查了一下privilege 3 0 -0.5001426003678001 0 0 1 0 1.0205040739539888
@yi_yun118 0 0 0.29242417651199304 0 0 1 0 0.7307821467427014
卡 0 0 -0.5566518076134661 0 0 1 0 1.5507082063554192
課題分離~ 3 0 0.02997201989300602 0 0 1 0 0.528884272662012
想知道設計師 1 0 -2.031469668951889 0 0 1 0 3.1476648393891007
知道要表達什麼 1 0 -1.10120012212523 0 0 1 0 1.742446282305988
公主要貸款? 0 0 -0.3714880915344334 0 0 1 0 0.9218583587854745
學費了嗎 0 0 -0.9875300974973007 0 0 1 0 1.2815582088349062
幸運的我 接下來就是開始房貸人生 0 0 -0.2861858394628365 0 0 1 0 0.9841637973284564
我這樣算整頓職場嗎? 1 0 -0.3079486530206824 0 0 1 0 1.016091969722521
privilege 這個字只能用複製的 1 0 -0.9831746995029098 0 0 1 0 1.0817608785197124
懂了嗎 1 0 -0.947187933736089 0 0 1 0 1.6790177606648218
我是4473🫠 0 0 -0.3231551917528649 0 0 1 0 1.0936771089940382

1 text group center_x center_y center_z axis_x axis_y axis_z radius
2 大家看不懂 3 0 -0.4123532324273361 0 0 1 0 1.0372877294442566
3 你哪來的學貸? 0 0 -0.749867176413578 0 0 1 0 0.7548669135932486
4 介面超難用 2 0 -0.2408329902995598 0 0 1 0 0.4194029232209698
5 真的嗎 0 0 0.4623510329966389 0 0 1 0 1.5048125315303627
6 我打開是英文的 2 0 -0.7368388135608597 0 0 1 0 0.8494843186786402
7 連結: skills.google 3 0 0.139395989566791 0 0 1 0 1.5977131286124318
8 這肯定不是最近的 0 0 0.3370488241260117 0 0 1 0 1.4914315633910131
9 幸運的我 接下來就是開始房貸人生 0 0 -0.19097668520390787 0 0 1 0 0.8094034955180638
10 我買170 0 0 -1.1429481166751554 0 0 1 0 2.0670878753324895
11 你哪來的學貸? 0 0 -0.6076332826864907 0 0 1 0 0.831596719738272
12 你到底知不知道外面用人市場 3 0 0.24217833683989254 0 0 1 0 0.6471301997319437
13 無法同意您更多~ 1 0 -0.6491252211789924 0 0 1 0 0.8838320528906913
14 邊讀邊還 0 0 0.01362608847808855 0 0 1 0 0.4560166636586928
15 還沒看懂在討論什麼 1 0 -0.42005793241928235 0 0 1 0 0.6063709493275319
16 那什麼啦 0 0 -0.9619281018682606 0 0 1 0 1.562724354763271
17 請問出處 2 0 -1.850633716215873 0 0 1 0 2.5764247392782
18 你看差多少 0 0 0.06565028895161262 0 0 1 0 1.325940426133994
19 學貸晚點還沒關係 0 0 0.2527370656563437 0 0 1 0 0.41113186647926575
20 最近也考慮買一間 0 0 -1.3493273548166158 0 0 1 0 1.7581974612719224
21 最近貸款通過的朋友 0 0 0.38717201572801146 0 0 1 0 1.2072201654367076
22 @ariki_fudo66 1 0 -0.15040365289201324 0 0 1 0 0.7017093686995065
23 商家老闆再次 請慢用 0 0 -0.919191543387093 0 0 1 0 2.289049732331217
24 來玩ㄇ 0 0 -1.09850381870088 0 0 1 0 2.3271496457556493
25 哪裡找字幕 1 0 -0.2829123163571337 0 0 1 0 0.9044507454678385
26 公司幫妳付房貸 0 0 -1.1904257349467433 0 0 1 0 1.4597990188612395
27 超值! 0 0 -1.2767048888866745 0 0 1 0 2.2807317610058684
28 可以聊聊唷~ 0 0 0.4291699409620805 0 0 1 0 0.8488469451510265
29 請問您使用5的couesera 0 0 -0.29592086016284935 0 0 1 0 2.2052729631614167
30 我貸款也要去租 0 0 -0.8632559828838402 0 0 1 0 1.6100039168811777
31 別把負債想的太可怕 0 0 -0.6581992846805238 0 0 1 0 0.8823466887149647
32 附上網頁連結 2 0 -0.23352137567511216 0 0 1 0 0.587397373356631
33 請各位用低收入戶稱呼 2 0 -1.1677991871458164 0 0 1 0 1.7900899890708353
34 好辦法 1 0 -0.3040354768710512 0 0 1 0 0.6092131083608139
35 有保證付多少年嗎 0 0 -0.9288624221613426 0 0 1 0 1.1682449839328297
36 TOEFL GRE 等級單字 1 0 -1.1760779337182221 0 0 1 0 1.1987248938430015
37 會考根本不到比天賦 3 0 0.06603930321894402 0 0 1 0 0.4665953643001922
38 如果隔壁現在開一倍 0 0 -1.3532551932477486 0 0 1 0 1.9823045326399789
39 查了一下privilege 3 0 -0.5001426003678001 0 0 1 0 1.0205040739539888
40 @yi_yun118 0 0 0.29242417651199304 0 0 1 0 0.7307821467427014
41 0 0 -0.5566518076134661 0 0 1 0 1.5507082063554192
42 課題分離~ 3 0 0.02997201989300602 0 0 1 0 0.528884272662012
43 想知道設計師 1 0 -2.031469668951889 0 0 1 0 3.1476648393891007
44 知道要表達什麼 1 0 -1.10120012212523 0 0 1 0 1.742446282305988
45 公主要貸款? 0 0 -0.3714880915344334 0 0 1 0 0.9218583587854745
46 學費了嗎 0 0 -0.9875300974973007 0 0 1 0 1.2815582088349062
47 幸運的我 接下來就是開始房貸人生 0 0 -0.2861858394628365 0 0 1 0 0.9841637973284564
48 我這樣算整頓職場嗎? 1 0 -0.3079486530206824 0 0 1 0 1.016091969722521
49 privilege 這個字只能用複製的 1 0 -0.9831746995029098 0 0 1 0 1.0817608785197124
50 懂了嗎 1 0 -0.947187933736089 0 0 1 0 1.6790177606648218
51 我是4473🫠 0 0 -0.3231551917528649 0 0 1 0 1.0936771089940382

@ -1 +1,5 @@
id text tx ty tz group dist
3 學貸 5.006850706144017 -0.3937508764344644 -3.8028395349683612 0 0.6999431120800679
10 邊界 8.42051332674133 -0.6725770506631371 -4.245520249697503 1 0.25132005276280606
15 主體 7.641380380701039 0.17865233926193508 -3.224946864645592 2 0.11523702488157918
17 誰懂 8.107236364520066 0.13964310414056988 -3.6591765364180584 3 0.09811323645749676

1 id text tx ty tz group dist
2 3 學貸 5.006850706144017 -0.3937508764344644 -3.8028395349683612 0 0.6999431120800679
3 10 邊界 8.42051332674133 -0.6725770506631371 -4.245520249697503 1 0.25132005276280606
4 15 主體 7.641380380701039 0.17865233926193508 -3.224946864645592 2 0.11523702488157918
5 17 誰懂 8.107236364520066 0.13964310414056988 -3.6591765364180584 3 0.09811323645749676

@ -1,2 +1,2 @@
id text updateTime id text updateTime
4 租屋 1772962792 3 學貸 1773050988

1 id text updateTime
2 4 3 租屋 學貸 1772962792 1773050988

@ -0,0 +1,262 @@
import math as _m, random as _r
_FLOAT=0; _GATHER=1; _LINES=2; _LFADE=3; _EXPAND=4; _ELLIPSE=5
_CHAR_W_LATIN=10.0; _CHAR_W_CJK=18.0; _SLOTS_PER_LBL=20
def _cjk(ch): return '\u4e00'<=ch<='\u9fff'
def _tier():
x=_r.random()
return 0 if x<0.3 else (1 if x<0.7 else 2)
def _spd(t,s1,s2,s3):
if t==0: return _r.uniform(s1*.8,s1*1.2)
if t==1: return _r.uniform(s2*.8,s2*1.2)
return _r.uniform(s3*.8,s3*1.2)
def _dir(): return -1 if _r.random()>0.1 else 1
def _cpos(i,W,H):
a=i/18*2*_m.pi-_m.pi/2
r=min(W,H)*.28
return W/2+r*_m.cos(a), H/2+r*_m.sin(a)
def _epos(i,W,H):
a=i/18*2*_m.pi-_m.pi/2
return W/2+W*.47*_m.cos(a), H/2+H*.43*_m.sin(a)
def _ease(t):
t=max(0.,min(1.,t))
return 2*t*t if t<.5 else -1+(4-2*t)*t
def _init_bg(W,H,s1,s2,s3):
out=[]
for i in range(80):
t=_tier()
out.append({'x':_r.uniform(0,W),'y':i/80*H,'speed':_spd(t,s1,s2,s3)*_dir()})
return out
def _init_cd(W,H,s1,s2,s3,cw):
out=[]
for i,w in enumerate(cw):
t=_tier()
out.append({'x':_r.uniform(0,W),'y':_r.uniform(0,H),'speed':_spd(t,s1,s2,s3)*_dir(),'idx':i,'word':w})
return out
def _build_rows(nr,rs,wpr,W,H,aw,s1,s2,s3):
fs=max(12,min(80,int(W*.85/max(1,wpr*12)/(10/18)*18)))
cw=fs*.6; out=[]
for i in range(nr):
t=_tier(); sp=_spd(t,s1,s2,s3)*_dir()
sel=_r.choices(aw,k=wpr) if aw else []
gaps=[_r.uniform(60,140) for _ in range(max(0,wpr-1))]
wws=[max(40,len(w.get('english',''))*cw) for w in sel]
tw=sum(wws)+sum(gaps)
sx=_r.uniform(-tw*.5,W-tw*.3)
wr=[]; x=sx
for j,w in enumerate(sel):
wr.append({'id':w['id'],'text':w['english'],'x':x,'width':wws[j]})
x+=wws[j]+(gaps[j] if j<len(gaps) else 0)
out.append({'words':wr,'y':120+i*rs,'speed':sp,'total_w':tw})
return out
def frameEnd(frame):
try: _run(frame)
except Exception as e: print('FE err:',e)
def _run(frame):
root=op('/project1/deep_sound')
W=root.par.Resw.val; H=root.par.Resh.val; dt=1
s1=root.par.Speedslow.val; s2=root.par.Speedmid.val; s3=root.par.Speedfast.val
wpr=int(root.par.Wordsperrow.val)
es=root.par.Expandspd.val; ds=root.par.Drawspd.val; ms=root.par.Marqueespd.val
gw=root.par.Gatherwait.val; lp=root.par.Linepause.val; fo=root.par.Fadeout.val
mcs=root.par.Marqueecharspacing.val; mcsz=root.par.Marqueesize.val
# Read state from stored dict
_DEF={'appState':_FLOAT,'textAlpha':1.,'gatherTimer':-1.,'pauseTimer':-1.,
'dissolving':0,'ellipseAlpha':1.,'currentSeg':0,'labelFadeProgress':0.,
'expandT':0.,'ellipseDrawT':0.,'marqueeAngle':0.,'marqueeAlpha':0.,
'lineAlpha':0.,'pid0':0,'pid1':0,'pid2':0,'pid3':0}
st=root.fetch('state_dict', None)
if st is None: st=dict(_DEF)
ast=int(round(st['appState']))
ta=float(st['textAlpha']); gt=float(st['gatherTimer']); pt=float(st['pauseTimer'])
dv=int(round(st['dissolving'])); ea=float(st['ellipseAlpha']); cs=int(round(st['currentSeg']))
lfp=float(st['labelFadeProgress']); et=float(st['expandT']); edt=float(st['ellipseDrawT'])
mang=float(st['marqueeAngle']); malp=float(st['marqueeAlpha'])
pid0=int(round(st['pid0'])); pid1=int(round(st['pid1']))
pid2=int(round(st['pid2'])); pid3=int(round(st['pid3']))
pids=[pid0,pid1,pid2,pid3]
bg=root.fetch('bg_dots',None); cd=root.fetch('circle_dots',None)
rows=root.fetch('rows',None); segs=root.fetch('line_segs',[])
las=root.fetch('label_alphas',[0.,0.,0.,0.])
wdat=op('words_table'); aw=[]; cw=[]
for r in range(1,wdat.numRows):
w={'id':int(wdat[r,'id'].val),'english':str(wdat[r,'english'].val),
'chinese':str(wdat[r,'chinese'].val),'circle':int(wdat[r,'circle'].val)}
aw.append(w)
if w['circle']==1: cw.append(w)
ts_div=[1,2,3][min(2,max(0,root.par.Textsize.menuIndex))]
fs=max(12,min(80,int(W*.85/max(1,wpr*12)/(10/18)*18)))//ts_div
nr=max(8,int((H-120)/max(1,fs*1.6))); rs2=(H-120)/max(1,nr-1)
pw=root.fetch('prev_wpr',-1); ps=root.fetch('prev_s1',-999.); pts=root.fetch('prev_ts',-1)
if bg is None or rows is None or cd is None or pw!=wpr or abs(ps-s1)>.001 or pts!=ts_div:
bg=_init_bg(W,H,s1,s2,s3)
cd=_init_cd(W,H,s1,s2,s3,cw)
rows=_build_rows(nr,rs2,wpr,W,H,aw,s1,s2,s3)
root.store('prev_wpr',wpr); root.store('prev_s1',s1); root.store('prev_ts',ts_div); root.store('font_size',fs)
fi_spd=root.par.Fadein.val; fo_spd=root.par.Fadeoutspd.val
ta=max(0.,ta-fo_spd) if ast!=_FLOAT else min(1.,ta+fi_spd)
for row in rows:
for wd in row['words']: wd['x']+=row['speed']*dt
if row['words']:
lft=min(wd['x'] for wd in row['words'])
rgt=max(wd['x']+wd['width'] for wd in row['words'])
sh=W+row['total_w']+160
if row['speed']<0 and rgt<-80:
for wd in row['words']: wd['x']+=sh
elif row['speed']>0 and lft>W+80:
for wd in row['words']: wd['x']-=sh
for d in bg:
d['x']+=d['speed']*dt
if d['speed']<0 and d['x']<-80: d['x']+=W+160
elif d['speed']>0 and d['x']>W+80: d['x']-=W+160
for i,d in enumerate(cd):
if ast==_FLOAT:
d['x']+=d['speed']*dt
if d['speed']<0 and d['x']<-80: d['x']+=W+160
elif d['speed']>0 and d['x']>W+80: d['x']-=W+160
elif ast in (_GATHER,_LINES,_LFADE):
tx,ty=_cpos(i,W,H)
d['x']+=(tx-d['x'])*.04*dt; d['y']+=(ty-d['y'])*.04*dt
elif ast==_EXPAND:
tx,ty=_cpos(i,W,H); ex,ey=_epos(i,W,H); t=_ease(et)
d['x']=tx+(ex-tx)*t; d['y']=ty+(ey-ty)*t
elif ast==_ELLIPSE:
ex,ey=_epos(i,W,H); d['x']=ex; d['y']=ey
if ast==_GATHER:
gt-=dt/60.
if gt<=0:
p=sorted(_r.sample(range(18),4)); pid0,pid1,pid2,pid3=p; pids=p
segs=[{'from_idx':p[k],'to_idx':p[k+1],'progress':0.,'done':False} for k in range(3)]
las=[0.,0.,0.,0.]; cs=0; ast=_LINES
elif ast==_LINES:
if cs<len(segs):
segs[cs]['progress']=min(1.,segs[cs]['progress']+.012*dt)
if segs[cs]['progress']>=1. and not segs[cs]['done']:
segs[cs]['done']=True; cs+=1
las[0]=min(1.,las[0]+.02*dt)
if len(segs)>0 and segs[0]['done']: las[1]=min(1.,las[1]+.02*dt)
if len(segs)>1 and segs[1]['done']: las[2]=min(1.,las[2]+.02*dt)
if len(segs)>2 and segs[2]['done']: las[3]=min(1.,las[3]+.02*dt)
if all(s['done'] for s in segs) and all(a>=1. for a in las) and pt<0:
pt=lp
if pt>=0:
pt-=dt/60.
if pt<=0: pt=-1; ast=_LFADE; lfp=0.
elif ast==_LFADE:
lfp=min(1.,lfp+.015*dt)
if lfp>=1.: ast=_EXPAND; et=0.
elif ast==_EXPAND:
et=min(1.,et+es*dt)
if et>=1.: ast=_ELLIPSE
elif ast==_ELLIPSE:
edt=min(1.,edt+ds*dt)
mang-=ms*dt
if edt>=1.: malp=min(1.,malp+.012*dt)
if dv:
ea=max(0.,ea-dt/max(.001,fo*60.))
if ea<=0.:
ast=_FLOAT; dv=0; ea=1.; edt=0.; mang=0.; malp=0.; ta=0.
et=0.; lfp=0.; gt=-1.; pt=-1.; pids=[0,0,0,0]; segs=[]; las=[0.,0.,0.,0.]; cs=0
pid0=pid1=pid2=pid3=0
bg=_init_bg(W,H,s1,s2,s3); cd=_init_cd(W,H,s1,s2,s3,cw)
prox=[]
if ast==_FLOAT:
for i in range(len(bg)):
for j in range(i+1,len(bg)):
dx=bg[i]['x']-bg[j]['x']; dy=bg[i]['y']-bg[j]['y']
dist=_m.sqrt(dx*dx+dy*dy)
if dist<90: prox.append((dist,i,j))
prox.sort(); prox=prox[:int(root.par.Maxlinks.val)]
# Line alpha for Level TOP (no Python alpha math in render)
line_alpha=1. if ast==_LINES else (1.-lfp if ast==_LFADE else 0.)
# Update line-label Text TOPs
for i in range(4):
did=pids[i] if i<len(pids) else 0
chi=''; eng=''
if 0<=did<len(cd):
w=cd[did].get('word',{}); chi=w.get('chinese',''); eng=w.get('english','')
ch_t=root.op(f'lbl_ch_{i}'); en_t=root.op(f'lbl_en_{i}')
if ch_t: ch_t.par.text=chi
if en_t: en_t.par.text=eng
# Update chr_sop fontsizex if Marqueesize changed
pmcsz=root.fetch('prev_mcsz',-1.)
if abs(pmcsz-mcsz)>0.1:
for idx in range(80):
s=root.op(f'marq_geo/chr_sop_{idx:02d}')
if s: s.par.fontsizex=mcsz
root.store('prev_mcsz',mcsz)
# Per-character marquee placement along ellipse
rx_m=W*0.47-34; ry_m=H*0.43-24
for qi in range(4):
ang=mang+qi*_m.pi/2
did_q=pids[qi] if qi<len(pids) else 0
lbl=''
if 0<=did_q<len(cd):
w=cd[did_q].get('word',{}); chi=w.get('chinese',''); eng=w.get('english','')
lbl=f'{chi} {eng}'.strip() if chi else eng
t=ang; base_slot=qi*_SLOTS_PER_LBL
cw_lat=mcsz*0.56; cw_cjk=mcsz
for ci in range(_SLOTS_PER_LBL):
idx=base_slot+ci
sop=root.op(f'marq_geo/chr_sop_{idx:02d}')
tf=root.op(f'marq_geo/chr_tf_{idx:02d}')
if ci<len(lbl):
ch=lbl[ci]
cw=cw_cjk if _cjk(ch) else cw_lat
x=rx_m*_m.cos(t); y=ry_m*_m.sin(t)
rot=_m.degrees(_m.atan2(ry_m*_m.cos(t),-rx_m*_m.sin(t)))
if sop: sop.par.text=ch
if tf: tf.par.tx=round(x,3); tf.par.ty=round(y,3); tf.par.rz=round(rot,3)
ds_dt=_m.sqrt((rx_m*_m.sin(t))**2+(ry_m*_m.cos(t))**2)
t+=(cw+2)*mcs/max(1.,ds_dt)
else:
if sop: sop.par.text=''
if tf: tf.par.tx=0.; tf.par.ty=0.; tf.par.rz=0.
# Update custom params for Level TOP opacity drivers
root.par.Textalpha=round(ta,4)
root.par.Marqalpha=round(malp*ea,4)
root.par.Linealpha=round(line_alpha,4)
# Write all state back to dict (picked up by state_chop Script CHOP each frame)
root.store('state_dict',{'appState':ast,'textAlpha':ta,'gatherTimer':gt,'pauseTimer':pt,
'dissolving':dv,'ellipseAlpha':ea,'currentSeg':cs,'labelFadeProgress':lfp,
'expandT':et,'ellipseDrawT':edt,'marqueeAngle':mang,'marqueeAlpha':malp,
'lineAlpha':line_alpha,'marqAlpha':malp*ea,
'pid0':pid0,'pid1':pid1,'pid2':pid2,'pid3':pid3})
root.store('bg_dots',bg); root.store('circle_dots',cd); root.store('rows',rows)
root.store('line_segs',segs); root.store('label_alphas',las)
root.store('prox_pairs',prox)
def onStart(): pass
def onCreate(): pass
def onExit(): pass

@ -0,0 +1,47 @@
import numpy as _np
import math as _m
_FLOAT=0; _GATHER=1; _LINES=2; _LFADE=3; _EXPAND=4; _ELLIPSE=5
def onSetupParameters(scriptOp): pass
def onCook(scriptOp):
try:
_do_render(scriptOp)
except Exception as e:
import traceback; traceback.print_exc()
def _do_render(scriptOp):
from PIL import Image, ImageDraw
import 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'
if PIL_PATH not in sys.path:
sys.path.insert(0, PIL_PATH)
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)))
cd = root.fetch('circle_dots', [])
segs = root.fetch('line_segs', [])
img = Image.new('RGBA', (W, H), (0, 0, 0, 0))
if ast in (_LINES, _LFADE) and segs and cd:
draw = ImageDraw.Draw(img)
for seg in segs:
fi = seg.get('from_idx', 0); ti = seg.get('to_idx', 0)
prog = float(seg.get('progress', 0.))
if prog <= 0 or fi >= len(cd) or ti >= len(cd): continue
x0 = cd[fi]['x']; y0 = cd[fi]['y']
x1 = cd[ti]['x']; y1 = cd[ti]['y']
# Interpolate endpoint by progress
ex = x0 + (x1 - x0) * prog
ey = y0 + (y1 - y0) * prog
draw.line([(x0, y0), (ex, ey)], fill=(255, 255, 255, 255), width=2)
arr = _np.ascontiguousarray(_np.flipud(_np.array(img, dtype=_np.float32) / 255.))
scriptOp.copyNumpyArray(arr)

@ -0,0 +1,127 @@
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)

@ -0,0 +1,27 @@
_FLOAT=0; _GATHER=1; _LINES=2; _LFADE=3; _EXPAND=4; _ELLIPSE=5
def _toggle():
root=op('/project1/deep_sound')
st=root.fetch('state_dict', None)
if st is None: return
ast=int(round(st.get('appState',_FLOAT)))
if ast==_FLOAT:
st['appState']=_GATHER
st['gatherTimer']=root.par.Gatherwait.val
elif ast in (_EXPAND,_ELLIPSE):
st['dissolving']=1
else:
st.update({'appState':_FLOAT,'dissolving':0,'ellipseAlpha':1.,'ellipseDrawT':0.,
'marqueeAngle':0.,'marqueeAlpha':0.,'expandT':0.,'labelFadeProgress':0.,
'gatherTimer':-1.,'pauseTimer':-1.,'pid0':0,'pid1':0,'pid2':0,'pid3':0,
'currentSeg':0,'textAlpha':1.,'lineAlpha':0.,'marqAlpha':0.})
root.store('line_segs',[])
root.store('label_alphas',[0.,0.,0.,0.])
root.store('state_dict', st)
root.par.Textalpha=float(st.get('textAlpha',1.))
def onOffToOn(channel,sampleIndex,val,prev): _toggle()
def onOnToOff(channel,sampleIndex,val,prev): pass
def onValueChange(channel,sampleIndex,val,prev): pass
def onWhileOn(channel,sampleIndex,val,prev): pass
def onWhileOff(channel,sampleIndex,val,prev): pass

@ -0,0 +1,48 @@
import numpy as _np
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 = {}
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 _dtxt(draw, text, x, y, sz, col):
cx=float(x)
for ch in text:
f=_font(_cjk(ch),sz)
try:
bb=draw.textbbox((0,0),ch,font=f)
draw.text((cx,y-sz*.55),ch,font=f,fill=col)
cx+=bb[2]-bb[0]
except: cx+=sz*.6
def onSetupParameters(scriptOp): pass
def onCook(scriptOp):
try:
if _PIL_PATH not in _sys.path: _sys.path.insert(0,_PIL_PATH)
from PIL import Image, ImageDraw
root=op('/project1/deep_sound')
W=int(root.par.Resw.val); H=int(root.par.Resh.val)
rows=root.fetch('rows',[]); fs=root.fetch('font_size',18)
img=Image.new('RGBA',(W,H),(0,0,0,0)) # transparent background
draw=ImageDraw.Draw(img)
for row in rows:
for wrd in row['words']:
_dtxt(draw,wrd['text'],wrd['x'],row['y'],fs,(255,255,255,255))
arr=_np.ascontiguousarray(_np.flipud(_np.array(img,dtype=_np.float32)/255.))
scriptOp.copyNumpyArray(arr)
except Exception as e:
import traceback; traceback.print_exc()

Binary file not shown.
Loading…
Cancel
Save