2
Help us understand the problem. What are the problem?

posted at

updated at

TouchDesignerでPythonを使ってみたい

普段はWebアプリ開発、データ解析みたいなことをPythonでやっているのですが、
ひょんなことからDMX, ArtNet, Arduino, Neopixel等を触る機会がありまして、
その延長上で「TouchDesingner」というものを知りました。

プログラミングとPCだけで渡り歩く「情報」の世界から、我々の肉体が存在する「物理世界」への"バックドア"を見つけたような気がして面白そうだったので、
まったくのTouchDesigner初心者ですが、TDでPythonを使ってみるにはどうすればいいのかをちょっとだけ調べてだいぶ雑にまとめてみます。

TouchDesignerのインストール

お使いの環境に合わせて↓からインストールすればいいのだと思います!
非商用の個人利用なら無料らしいです。感謝。

TouchDesignerの使い方

TouchDesigner自体の使い方の記事はいっぱいあるので割愛します!
↓とかいいのかも?

TouchDesignerでPythonを使う

ここからが本題。
いかにしてPythonを使えばよいのやら。
ということで調べて見ると、TouchDesignerを作っている会社であるDerivativeさんが丁寧に説明してくれています。
(そもそもTDのドキュメント全般をWikiで書いてくれているっぽいですね。)

今回は、このチュートリアルをちょっとだけ紹介していきたいと思います。
とりあえず、TouchDesignerを開いて、最初に表示されている箱をCtrl+A→Deleteで削除しておきましょう。

文字列の表示

一応チュートリアルということなので、まずText TOPにPythonの値を表示してみます。
(TOPというのは"Texture Operator"のことで画像をこねくり回すことができる箱です。)

Tabキーを開いて、「text」と入力し、
image.png
Text TOPを見つけて配置します。
image.png
こんな感じでデフォルトでは"derivative"が表示されます。
右上にあるのは、「パラメータウィンドウ」といって、箱が持っているパラメータの一覧です。(表示されていない場合はキーボードの「p」を押すと表示/非表示を切り替えれます。)

パラメータウィンドウの「Text」タブの「Text」パラメータをクリックします。
image.png
すると、パラメータが下部に展開されるので、
青い四角形(カーソルを当てると「expression」と表示される)をクリックして、右側の入力欄にPythonの文字列みたく

'Hello Python'

と入力すると、

image.png

image.png

おー、'Hello Python'という文字列が画像として表示されました。
このままだと、文字列を表示するのと何も変わらないので、足し算にしてみます。

'Hello ' + 'Python'

image.png

おー、ちゃんと文字列の結合がされている。
どうせなら、もう少しPythonっぽいことがしたいので、関数を記述してみます。

Textパラメータを

dir()

として(dir関数はスコープにある名前のリストを表示してくれます)、Word WrapパラメータをOnにすると、
image.png

おー!呼び出せそうな変数、関数が表示されている!

こんな感じで、パラメータウィンドウに1行だけ(?)Pythonを記述できるらしいです。

TouchDesignerのオブジェクト

TouchDesignerでは、箱(ノード、オペレータ)を繋げていって処理を行うわけですが、
Pythonを記述する場合には、自分自身の持っているパラメータや、他のノードのパラメータを取得したい場合があります。
そのためには、meクラスとかopクラスとかparentクラスを使います。

  • meクラス:自分自身
  • opクラス:オペレータ(箱)を取得できるクラス
  • parentクラス:親オペレータ

まだ勉強中なので詳しく説明できないのですが、とりあえず箱(オペレータ)のパラメータをPythonで取得したい場合は、今紹介した人たちを使えば良いらしいです。
オペレータの名前は、

オペレータ.name

で取得できます。

また、箱(オペレータ)の持っているパラメータにはparクラスで参照できます。

  • parクラス:パラメータ達にアクセスできるクラス

たとえば、

me.par.text # 自分自身のTextパラメータ
op('text2').par.fontsizex # text2オペレータのFont Size X パラメータ

みたいな感じです。

パラメータウィンドウに表示されているパラメータのparクラスにおけるプロパティ名を知りたい場合は、
ウィンドウで各パラメータをクリックすると下部に展開される入力欄の左側を見れば確認できます。
たとえば、下の画像の「Font Size Xパラメータ」のプロパティ名は「fontsizex」です。
スクリーンショット 2021-12-16 173040.png

TouchDesignerには音声とか信号を扱えるCHOP(CHannel OPerators)もあります。
CHOPは「チャンネル」といって、Pythonのリストのように複数の値を持っている場合が多いです。
実際に、CHOPを作ってみます。
Tabキーを押して、「Constant」と入力して、Constant CHOPを探してEnterを押すと、画面にConstant CHOPが追加されます。
パラメータウィンドウのConstantタブで下部の「+」ボタンを押すとチャンネルを増やすことができます。
さらに、valueを適当にいじると下の画像みたいになります。
chan1chan2の2つのチャンネルがあります。)
image.png
このConstant CHOPのチャンネルを取得したい場合は、

op('constant1')['chan1'] # constant1オペレータの'chan1'チャンネル

みたいに、辞書型のイメージでチャンネル名を指定すれば値を取得できます。

ここで、パラメータとかチャンネルを取得するときに注意なのが、関数の引数とかに指定しようとするとエラーを吐く場合がある、ということです。
これは、実際に取得されるのが値そのものではなくTouchDesignerのクラスだったりするのが理由です。
値を取得したい場合には、

op('constant1')['chan1'].eval()

みたく、evalメソッドを使うと良いらしいです。
round関数で丸めるときなどは注意しましょう。

シェルを開いて実行したい-Textportについて-

ここまでは、Text TOPのパラメータにPythonっぽいことを書く、というThe初心者って感じの方法でPythonを使ったわけですが、
当然ながらもっとスマートな方法があります。
それが、Textportを使う方法です。
TouchDesignerの左上の「Pane Layout」から縦半分になっているものをクリックします。
image.png
すると、画面が2分割されるはずです。
さらに、
image.png
右側の画面の上部にある下三角をクリックして「Textport and DATs」をクリックすると、、、

おなじみPythonシェルが開きます!
image.png

では早速Textportから、TouchDesignerのオブジェクトを触ってみましょう。
さっき設置したconstant1 CHOPを取得してみます。

python >>> r = op('constant1')
python >>> debug(r) # debug関数を使うと呼び出し元がわかるから便利らしい!
# 実行結果 -> None (Debug - DAT:<Textport> fn:<module> line:1)

となり、取得できていない!
これは、Textportがある場所からはconstant1 CHOPを直接呼び出せないからです。(スコープの問題みたいな?)

呼び出すためには、ちゃんとパスを指定しなければならないのですが、
どうすればいいのかというと、「ドラッグアンドドロップ」!

r = op('# ここにドラッグアンドドロップ

自動でパスを入力してくれるので、そのままパスの文字列を閉じればOK!

実際にやってみると
image.png
こんな感じになります。
なるほど、constant1はproject1の中にあったということがわかりますね。

スクリプトを書いて実行したい-DATについて-

これまでは「Pythonをオペレータのパラメータで使う」、「Textportで対話型で使う」という方法をとってきました。
しかし、実際はあらかじめ書かれたコードを実行したいですよね。
(そうしないとPythonを書く意味が、、、)

ということで、DAT(Data Operator)を使ってみましょう。(DATは文字列、スクリプト、XMLなどのテキストデータを扱うらしいです。)
DATを使うことで、Pythonスクリプトを実行することができるようになるので、TouchDesignerでプログラミングしてる感がでてきます!(たぶん。)

DATでPythonを扱うには、いくつかの方法があるらしいです。

  1. Callbacks, Execute DATs
    TouchDesignerでの種々の変化に合わせて実行される. onValueChangeとか。
  2. Script OPs
    スクリプトを使ってCHOP,DAT,SOP,TOPを作る
  3. Extenstions
    Pythonを使ってメソッドとか変数を拡張できるらしい
  4. Module
    モジュールとして扱える

大まかにはこの4つの方法があるらしいです。
インタラクティブな表現っていったら、やっぱり1のCallbackとかが入りやすいのかなって思ったりします。
(もっとちゃんとやると、2,3,4をゴリゴリに書いたりするのかな、、、)

そろそろ疲れてきたので、1のCallbackだけを紹介して終わりたいと思います。
チュートリアルにあるように、TouchDesignerの時間経過に合わせて背景色が変化するText TOPを作ってみましょう。
まずは、TouhDesignerの時間経過をText TOPに表示することにします。
Text TOPのTextパラメータに

absTime.frame

と入力しましょう。
image.png
すると目まぐるしく数字が変わる画像が表示されると思います。
image.png

次に、パラメータの変化に応じてメソッドの実行を指定できるParameter Execute DATを配置します。
image.png
こんな感じになるはずです。
image.png

続いて、Parameter Execute DATのパラメータウィンドウのOPsパラメータにText TOPをドラッグアンドドロップします。(ドラッグ中は矢印みたいなのがでるはずです。)
すると、Text TOPからParameter Execute DATに向かってなんか流れます。
image.png
さらに、Parametersパラメーラ(わかりづらいですね笑)に、Text TOPの指定したパラメータ名を入力します。この場合は、textパラメータです。
image.png
あとは、Parameter Execute DATの中身を書き換えれば、Text Topのtextパラメータに応じた処理ができます!

ひとまず、onValueChangeメソッドをパラメータをTextportに表示するように変更しましょう。
テキストを変更するには、箱の右下の「+」マークみたいなのを押した後、箱の中身をクリックすればできます。

def onValueChange(par, prev):
    debug(par)
    return

image.png

あとは、「Altキー」+「T」でTextportを開いてメソッドが実行されていることを確認しましょう。
image.png
実行されているのが確認できればOKです。

目的は背景色を変えることなので、onValueChangeの処理を書き換えましょう。

import random

def onValueChange(par, prev):
    op('text1').par.bgcolorr = random.random()
    op('text1').par.bgcolorg = random.random()
    op('text1').par.bgcolorb = random.random()
    return

これで行けるかと思いきや、変わっていません。
そこで、Text TOPのパラメータウィンドウのColorタブを開いてみると、
image.png
たしかにBackground Colorは変わっています。
ただ、Background Alphaが0のままで透明になっていました。
そこで、Background Alphaを1にしてみます。
image.png
おー。ようやく目的の背景色が変わるText TOPを作ることができました。

まとめ

この記事では、ただチュートリアルをものすごく雑に訳しただけになってしまったのですが、本当はもっと面白いことがやってみたいです。
今後も少しずつ勉強していきたいと思います。
TouchDesigner自体のチュートリアルはいっぱいあるし、Pythonどう使うかちゃんと書いてある記事もあると思うので、ぜひみなさんもエンタメPythonを楽しんでみてください!
(記事の間違いなどあればご教示願います!!!!)

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?