同じ物体をコピーして繰り返し位置をズラして配置できるようにしてみました。
もともと立方体(cube)などのデータは、dat.py d_setup(d) 関数で、 6つの四角平面(square)に展開されます。
d_setup(d)の呼び出し元の dat.py setup()では、
data = sum( map( d_setup, data ), [] )
などとしており、これは data = [ d, d, d, ... ] から d を取り出して d_setup(d) を呼び出してます。 d_setup(d) では d に処理を施し、結果を [ d ]、 あるいは複数に展開した後の [ d, d, d ... ] を返します。
それら [ [ d, d, ... ], [ d, d, ... ] ... ] を sum( ..., [] ) で連結して、 [ d, d, ... ] にしてます。
この仕組みを使って、d に「繰り返しコピー展開」の属性'rxs'があると、 d_setup(d) の中で複数のデータに展開して返すようにしてみました。
お試しデータは
dat.py : rxs_test = [ { 'kind': 'ball', 'rtd': rtd, 'm2g': [ ax.zoom_all(10), ax.slide([-15*4,-15*3,-15*2]) ], 'rxs': [ ( 'm2g', 'append', 4, [ ax.slide_x(30) ] ), ( 'm2g', 'append', 3, [ ax.slide_y(30) ] ), ( 'm2g', 'append', 2, [ ax.slide_z(30) ] ), ] },{ 'kind': 'ball', 'rtd': { 'diff': 0.3 }, 'maps': [ { 'fn': 'IMG_3999_3.mov', 'fn_r': 'IMG_3999_4.mov', 'r': 0.3, 'rep': (1,1) } ], 'm2g': [ ax.zoom_all(r) ], } ] :
rxs はリストで複数の rx を格納します。
rx とは
(コピーするときの変換位置, そこへの挿入か追加の指定, コピー数, 繰り返し施す変換)
そもそも物体のデータの構造は次のようになってます。
{ kind: 球(中心原点で半径1)とか、立方体(中心原点で一辺が-1から+1)とか l2m: 変換のリスト。上記のローカル座標系を、マッピング座標系に変換するためのもの m2g: 変換のリスト。マッピング座標系をグローバル座標系に変換するためのもの l2g: ローカル座標系からグローバル座標系に変換するためのもの (なければ d_setup() でl2m と m2g を連結して作られる) : }
物体を配置するときの処理を概念的に説明すると、次のような感じです。
例えば半径1の球は、l2m で拡大、縮小、変形などの変換をした後、画像を照射するマッピングのステージにあげます。
そこで画像データを、平行光線のように照射したり、点光源からの光のように照射したり、 はたまた直線を軸とする光源から円柱状に照射したりして、対象の球に画像を照らして焼き付けます。
画像が焼き付けられた球は、さらにm2gで変換してグローバル座標のステージに配置されます。
で、で、繰り返しコピー展開 rx に戻って、 (コピーするときの変換位置, そこへの挿入か追加の指定 ... ) は、 どの変換の段階でコピーするのかを指定します。
そして、指定の処理位置でコピー数分のコピーをとると、 rx の最後の指定の「繰り返し施す変換」をかけます。
最初の1つめのコピーは、変換なしのオリジナル。 次のコピーは「繰り返し施す変換」を1回かけたもの、 さらに次のコピーは「繰り返し施す変換」を2回かけたもの、...という具合。
まぁ処理の概念的には上記の通りですが、 実際の処理は、指定の変換リスト(l2mやm2g)の先頭か末尾に、 「繰り返し施す変換」を追加していくだけです。
そのrxによるコピーで1つのデータが複数になり。 rxs のリストから次の rx を取り出して処理すると、そのデータ群がコピーされて複数のデータ群に。 などと、rxs のリストが空になるまでコピーが繰り返されます。
dat.py のパッチは短いコードですが、かなり深い内容です。
+ if 'rxs' in d: + rxs = d.get('rxs') + if not rxs: + d.pop('rxs') + return d_setup(d) + (targ_k, i_a, n, lx) = rxs.pop(0) + + targ = d.get(targ_k, []) + ds = [] + for i in range(n): + d_ = d.copy() + d_['rxs'] = rxs[:] # ! + d_[targ_k] = targ[:] + ds.append(d_) + targ = lx + targ if i_a == 'insert' else targ + lx + return sum( map( d_setup, ds ), [] ) + ### +
画像サーバの中に動画書き込みの機能を入れ込んでましたが、 サーバの中でコネクションスレッドごとのロックとかがあり、 微妙に待ちが生じるので、別のサーバに分離しました。
ソースコードはimg.pyの中に一緒に入ってますが、 別のsrv.vwtサーバとして./img.py boot_vwt で起動します。
また、レイトレサーバに複数のピクセル位置をリストで渡していましたが、、、 ピクセル位置は連続保証にしたので、 「先頭のx,y位置」と「続く個数」的な情報で渡し、 可変長を嫌って固定長にしました。
あと、 遅いマシンでもrtサーバを上げて手伝ってもらう時でも、 あまり足をひっぱらないよう、割り当てるピクセル数を動的に調整する仕組みを入れてみました。
計算が終わってサーバを落とすとき用に、skill.sh を追加しました。 リモートマシンにも手伝ってもらう場合は、 skill.sh の後半部分のコメントを外すなり、変更して使います。
pythonのロックのメソッドacquire(), release()がイマイチしっくりこないので、 ut.py にラッパを用意して lock(), unlock() にしてみました。
$ mv rt_v35 rt_v36 $ cat v36.patch | ( cd rt_v36 ; patch -p1 ) $ cd rt_v36 $ make clean $ make
ではまず、速度確認。
$ ./cg.py eyep=[0,0,0],200,10 sec=10 data_name=objs name=out_v36/objs_1_2_sc n=1 init_sec=5 div=2 : wh : 76800/76800(100.0%) : fin 15.13s $ ./skill.sh
以前の v35 wh : 76800/76800(100.0%) : fin 16.16s v34 wh : 76800/76800(100.0%) : fin 38.47s v32 wh : 76800/76800(100.0%) : fin 26.84s v31 wh : 76800/76800(100.0%) : fin 40.50s v30 wh : 76800/76800(100.0%) : fin 38.39s v29 wh : 76800/76800(100.0%) : fin 1m 44.72s v28 wh : 76800/76800(100.0%) : fin 1m 18.06s v27 wh : 76800/76800(100.0%) : fin 1m 8.39s v26 wh : 76800/76800(100.0%) : fin 1m 6.02s (1-15.13/16.16)*100 = 6.37 パーセントの改善
ではお試しデータで、ワイヤーフレームから
$ ./cg.py eyep=[0,0,0],200,10 sec=10 data_name=rxs_test name=out_v36/rxs_test_wf wf : frm : 298/300(99.3%) : total 4m 30.31s : rest 1.80s : 2018/05/11 06:43:42 frm : 300/300(100.0%) : fin 4m 30.22s
-rw-r--r-- 1 kondoh staff 3588838 5 11 06:44 rxs_test_wf.mp4 3M超えてました。 $ ./img.py dmy out_v36/rxs_test_wf.mp4 cmd=3M $ cp v.mp4 out_v36/rxs_test_wf_3m.mp4
まぁ無事コピー展開できてる様子。 しかしワイヤーフレームでも10秒の動画生成に4分半、、、
荒削り設定で
$ ./cg.py eyep=[0,0,0],200,10 sec=10 data_name=rxs_test name=out_v36/rxs_test_es div=8 fps=10 : wh : 4800/4800(100.0%) : fin 1.89s frm : 100/100(100.0%) : fin 4m 39.54s
(4*60+39.54)*8*8*3/60/60 = 14.90 時間の予想
$ ./cg.py eyep=[0,0,0],200,10 sec=10 data_name=rxs_test name=out_v36/rxs_test : wh : 276167/307200(89.9%) : total 2m 22.12s : rest 14.35s : 2018/05/11 21:53:32 wh : 307200/307200(100.0%) : fin 2m 7.84s frm : 300/300(100.0%) : fin 14h 53m 45.76s ls -l out_v36/*.mp4 -rw-r--r-- 1 kondoh staff 12170547 5 11 21:53 out_v36/rxs_test.mp4 -rw-r--r-- 1 kondoh staff 1763037 5 11 06:58 out_v36/rxs_test_es.mp4 -rw-r--r-- 1 kondoh staff 3588838 5 11 06:43 out_v36/rxs_test_wf.mp4
予想時間通りではありますが、いやいや 12Mバイト! 3Mバイトに切り捨てるだけじゃなくて、3Mごとに分割するツールを作らねば。 (パッチは次回に含めます)
$ ./img.py dmy out_v36/rxs_test.mp4 cmd=div3M (n, fps)=(300, 30.0) : ./v.mp4 86/300 (n, fps)=(214, 30.0) : ./v.mp4 86/214 (n, fps)=(128, 30.0) ./v.mp4 86/128 $ ls -l out_v36/ total 61680 -rw-r--r-- 1 kondoh staff 12170547 5 11 22:08 rxs_test.mp4 -rw-r--r-- 1 kondoh staff 3145698 5 12 00:26 rxs_test_1.mp4 -rw-r--r-- 1 kondoh staff 3107714 5 12 00:27 rxs_test_2.mp4 -rw-r--r-- 1 kondoh staff 3113627 5 12 00:28 rxs_test_3.mp4 -rw-r--r-- 1 kondoh staff 2214859 5 12 00:28 rxs_test_4.mp4 :
しかし、同じVGA fps=30の3Mバイトの動画でも
このワイヤーフレームの二値の線画で8秒
色数も多いこれが18秒
これが2秒
そういうものなのだろうか。なんかどこかで間違ってたりしないだろうか?