こんにちは!こちらは TouchDesigner Advent Calendar 2023 12日目の記事です。
サンプル
今回作ったサンプルは以下にあります。
chimanaco/touchdesigner-advent-calendar-2023
はじめに
表題の件、Script TOP を使って OpenCV で顔認識をしてその位置を元に何か出す、ということをやっていた時に起こった問題について書いていきます。他にもっと根本的な解決方法がある気がしますが、自分の対処方法を残しておきます。
この記事のサンプルは 2023.11290 で作っていますが、2022.33910 でも同じでした。
うまくいかなかった例
script1_callbacks はこんな感じです(2023から const の value が value0 から const0value になった…?)。script1_callbacks で得られた値(サンプルではランダムな値にしています)を他で使用するべく Constant CHOP に入れています。
def onCook(scriptOp):
frame = op('SRC').numpyArray()
scriptOp.copyNumpyArray(frame)
op('constant1').par.const0value = tdu.rand(absTime.frame)
return
これが各オペレーターがあるネットワーク上だと更新されるものの Performance Mode にすると更新されなくなってしまいました。上の階層に行っても同様の症状でした。
うまくいった例
解決方法としてどこかで見かけたのが Storage を使う方法(フォーラムだったと思うのですが見つけたら追記します)です。Stroage を使うとオペレーターに紐づけて値を保存することができます。Constant CHOP の代わりに Script CHOP を使って実装します。
script1_callbacks はこんな感じです。scriptOp.store('var1', 10) のところで script1 に紐づけて var1 の値を保存しています。また、script2 の変数名と値を更新しています。scr.lock = True と scr.lock = False を入れておくと script1 と script2 の Loop を回避できます。
def onCook(scriptOp):
frame = op('SRC').numpyArray()
scriptOp.copyNumpyArray(frame)
# This fix the cooking bug
scriptOp.store('var1', 10)
scr = op('script2')
scr.lock = True
scr.clear()
tx = scr.appendChan('tx')
tx[0] = tdu.rand(absTime.frame)
scr.lock = False
return
script2_callbacks はこんな感じです。fetch() で script1 の Storage に保存されている値を読み込んでいます。
def onCook(scriptOp):
# Force creating a relation between script1 and script2
features = op('script1').fetch('var1')
return
これで無事 Performance Mode にしたり階層上がったりしても値が更新されるようになりました。
store する値はこのサンプルのように同じ値でも強制的に cook してくれるようです。サンプルだと Script TOP が cook されるごとに store() していますが、これを Execute DAT で onStart() で me.parent().store とかしてもうまくいきませんでした。また困ったことがあったら調べてみようと思います。
それではみなさま Happy Holidays!!
参考

