Script SOP 完全ガイド | 使い方・パラメータ解説【TouchDesigner】

※当サイトにはプロモーションリンクが含まれます。

Script SOP の Python ジオメトリ生成機能を示す図

記事更新の通知はXでアナウンス٩(๑❛ᴗ❛๑)
@maru6o6をフォロー

概要 📖 – Pythonスクリプトでジオメトリを動的生成・編集

Script SOPは、毎クックごとに Python スクリプトを実行し、ポイント・プリミティブ・頂点・属性を動的に生成・削除・編集できる SOPです。cook() / onPulse() / setupParameters() の 3 つの Python メソッドを編集することで、頂点座標から複雑なメッシュ・ベジェ曲線まで任意のジオメトリをデータ駆動で組み立てます。

主な用途 🎯

  • Python コードによるポイント・プリミティブの動的生成で、cook() 内から scriptOP API を呼び出し毎クックごとにジオメトリを再構築
  • カスタム属性および標準属性 (Cd / uv / N) の付与で、ポイントごとの色・UV・法線等を Python から自由に書き込み
  • ポリゴン・ベジェ曲線・メッシュ等多様なプリミティブ構築で、Python ループから addPoly / addBezier / addMesh 等を呼び任意形状を組み立て
  • 複数入力 SOP のジオメトリ統合・合成で、scriptOP.inputs 経由で 0 以上の入力ジオメトリを Python 側で結合・編集
  • setupParameters() による独自 UI パラメータ生成で、Setup Parameters ボタンを押した時点で Custom ページ上にカスタムパラメータを動的追加
  • onPulse() でのイベント駆動処理で、ユーザ定義のパルスパラメータを押した瞬間にジオメトリリセット・再生成等の処理を実行

データフロー 🔄

入力: 0 個以上の任意 SOP (scriptOP.inputs 経由でアクセス)

cook() メソッドが毎クック実行され Python から scriptOP API でポイント・プリミティブ・属性を生成・編集

出力: cook() が組み立てたジオメトリ (ポイント数・プリミティブ数は Python ロジック次第)

Tips

初心者の方は、以下日本語書籍も手元にあると安心です。

まる。
まる。

実際の案件事例まで踏み込んで紹介されていて、効率よくスキルアップするなら必携の二冊です!


パラメータ解説 ⚙️

Script Page 📁

Callbacks DAT の指定 🎛️

Callbacks DAT .callbacks 🎛️
cook() / onPulse() / setupParameters() の 3 メソッドを定義した DAT のパス
– デフォルトでは Script SOP 作成時に docked Text DAT (script1_callbacks) が自動生成され、この欄に自動セット
– 外部の Text DAT を指定して 1 つのコールバック実装を複数 Script SOP で共有することも可能
– 参照先 DAT を空にすると Script SOP は cook できずエラーになる

Setup Parameters の起動 ✨

Setup Parameters .setuppars
– パルスボタンとして 1 回押すと setupParameters(scriptOP) コールバックが呼び出される
– コールバック内で scriptOP.appendParFloat('ValueA', page='Custom') 等を呼ぶと Custom ページにカスタムパラメータが追加される
– パラメータの追加・削除・名前変更を行うたびに押すことで、UI を再構築
– 通常の cook 中には呼ばれないため、UI 構築コードと毎クックのジオメトリ生成コードを分離可能

Default Functions 📁

Script SOP 作成時に docked DAT として自動生成される 3 つの Python メソッド (Help → Python Examples / Operator Snippets も参照):

項目 内部名 説明

実践アイデア 💡

Example 1: 円周上に等間隔ポイントを cook() で動的生成する基本パターン ⭕

Script SOP (Callbacks=script1_callbacks, Custom: numPoints / radius) → Convert SOP → Material SOP → Render TOP

Script SOP の cook() 内で math.sin / math.cos を使い、Custom ページの numPointsradius から円周上のポイントを毎クック生成する最小構成のパターンです。setupParameters() で UI を作り、cook() 内で scriptOP.clear()appendPoint() ループで頂点を配置します。

  1. Script SOP を配置すると script1_callbacks という Text DAT が docked DAT として自動生成される
  2. setupParameters(scriptOP) 内に scriptOP.appendParInt('Numpoints', page='Custom')scriptOP.appendParFloat('Radius', page='Custom') を追加して Setup Parameters ボタンを押す
  3. cook(scriptOP) 内で scriptOP.clear() を呼んだ後、for i in range(scriptOP.par.Numpoints) ループで角度 theta = 2*math.pi*i/n を計算
  4. ループ内で p = scriptOP.appendPoint()p.P = (radius*math.cos(theta), 0, radius*math.sin(theta)) で 3D 座標を設定
  5. Custom ページの NumpointsRadius を変更するとリアルタイムで円周ポイントが更新されることを確認

Example 2: onPulse()で形状をイベント駆動リセット 💥

Script SOP (Custom: Generate パルス / Clear パルス) ← onPulse() で分岐 → Out SOP

setupParameters() で 2 つのパルスパラメータを追加し、onPulse(par) 内で par.name を見て分岐することで、UI ボタンに応じてジオメトリを新規生成したりクリアしたりするイベント駆動パターンです。cook() は最小限にし、状態変更は全て onPulse() 側で行います。

  1. setupParameters(scriptOP) 内で scriptOP.appendParPulse('Generate', page='Custom')appendParPulse('Clear', page='Custom') を追加
  2. Setup Parameters ボタンを押して Custom ページに 2 つのパルスボタンを表示
  3. onPulse(par) 内で if par.name == 'Generate': 分岐を作り、ランダム座標で scriptOP.appendPoint() をループ追加
  4. elif par.name == 'Clear': 分岐で scriptOP.clear() を呼んで全ジオメトリを削除
  5. Custom ページの Generate / Clear ボタンを押して、ジオメトリの追加・クリアがイベント単位で動くことを確認

Example 3: 複数SOPを合成しCd色をPythonで付与 🎨

Box SOP / Sphere SOP / Grid SOP → Script SOP (Callbacks: 3 入力をマージ + Cd 付与) → Geometry COMP → Render TOP

scriptOP.inputs 経由で 0 個以上の入力 SOP にアクセスし、各入力のポイント座標をコピーしながら入力番号ごとに異なる色 (Cd 属性) を付与するパターンです。scriptOP.appendCustomAttribute('Cd', 'vector') でカスタム属性を確保し、ポイントごとに色を書き込みます。

  1. Box SOP / Sphere SOP / Grid SOP の 3 つを Script SOP の 3 入力に接続
  2. cook(scriptOP) 内で scriptOP.clear() を呼んだ後、colors = [(1,0,0),(0,1,0),(0,0,1)] を準備
  3. for idx, inp in enumerate(scriptOP.inputs): ループで入力をイテレートし、各 inp.points から座標をコピーして scriptOP.appendPoint()
  4. ポイントごとに p.Cd = colors[idx] 等のかたちで色属性を書き込み
  5. Material SOP で頂点カラー対応のシェーダを適用、または Geometry COMP 経由で Render TOP に渡して 3 色合成形状が出ることを確認

関連オペレータ 🔗

類似機能OP 🔍

  • CPlusPlus SOP — C++ でジオメトリを動的生成 (Script SOP の Python 版に対して C++ ネイティブで高速処理)
  • DAT to SOP — Table DAT に記述したポイント・プリミティブを SOP に変換 (Script SOP よりも宣言的、テキストデータ駆動)

組み合わせ推奨OP 🔄

  • Script DAT — Script SOP の Callbacks DAT として参照する Python コールバック実装の入れ物
  • Script CHOP — 同じ Script 系のチャンネル版。CHOP データを Python で生成・編集
  • SOP to DAT — Script SOP が生成したジオメトリを Table DAT に書き出して検証・ロギング
  • Info CHOP — Script SOP 自体の num_points / num_prims / cook_time 等の状態を CHOP チャンネルとして取得
  • Geometry COMP — Script SOP が組み立てたジオメトリをレンダリングパイプラインに渡す出力先 COMP

前処理・後処理SOP 🎯


Info CHOP情報 📊

Script SOP は Info CHOP による詳細情報取得に対応しています。

ジオメトリ統計 📐

  • num_points: この SOP に含まれるポイント数
  • num_prims: この SOP に含まれるプリミティブ数
  • num_particles: この SOP に含まれるパーティクル数
  • last_vbo_update_time: last_vbo_update_time — 別スレッドで GPU 上にジオメトリ VBO を更新した所要時間 (通常のフレーム時間には含まれない)
  • last_meta_vbo_update_time: last_meta_vbo_update_time — メタサーフェス (metaballs / nurbs 等) の GPU 更新所要時間 (別スレッド)

GPU 転送タイミング 🎮

  • last_vbo_update_time: 別スレッドで SOP の CPU データを GPU 上のジオメトリデータに更新するのにかかった時間 (フレーム時間外)
  • last_meta_vbo_update_time: 別スレッドで metaball や NURBS のようなメタサーフェスジオメトリデータを GPU に更新するのにかかった時間 (フレーム時間外)

汎用オペレータ情報 🔄

  • total_cooks: プロセス開始以降にこのオペレータがクックされた合計回数
  • cook_time: 直近のクック所要時間 (ミリ秒)
  • cook_frame: このオペレータが最後にクックされたフレーム番号
  • warnings: このオペレータの警告数
  • errors: このオペレータのエラー数

クック統計 ⏱️

  • total_cooks: total_cooks — プロセス開始以降にこのオペレータがクックされた合計回数
  • cook_time: cook_time — 直近のクック所要時間 (ミリ秒)。Python ロジックの重さがそのまま反映される
  • cook_frame: cook_frame — このオペレータが最後にクックされたフレーム番号
  • cooked_this_frame: cooked_this_frame — 当該フレームでクックされた場合は 1
  • warnings: warnings — このオペレータに付いている警告数 (Python 内で scriptOP.addWarning を呼ぶと加算)
  • errors: errors — このオペレータに付いているエラー数 (Python 内で例外が発生したりエラーログが書かれると加算)

トラブルシューティング ⚠️

よくある問題と解決策 🔧

❌ Problem: cook() に書いたコードが思ったように実行されない / ジオメトリが出力されない
✅ Solution:

  • cook() の冒頭で scriptOP.clear() を呼んでいるか確認 — 呼ばないと前回のジオメトリが残り続けて新しい点が追加されるだけになる
  • Script ページの Callbacks DAT パスが正しい DAT を指しているか確認 — 空や存在しないパスだと cook 自体が実行されない
  • 対象 DAT のテキスト内で cook の関数シグネチャが def cook(scriptOP): になっているか (引数名は scriptOP 推奨、変えると参照系コードを総書換になりミスりやすい)

❌ Problem: Setup Parameters ボタンを押してもカスタムパラメータが出ない
✅ Solution:

  • setupParameters(scriptOP) 内で scriptOP.appendParFloat / appendParInt / appendParPulse 等の page='Custom' 指定を確認
  • Callbacks DAT 内に def setupParameters(scriptOP): 関数が定義されているか確認 — 関数名のタイポ (例: setupParameter 単数形) でも呼ばれない
  • Setup Parameters ボタンを 1 回押す必要がある。ファイルを開いた直後やコールバック編集後は手動で押し直さないと UI に反映されない

❌ Problem: 毎クック時のパフォーマンスが重い / 他のオペレータが描画追従しない
✅ Solution:

  • cook() 内でループ回数の多い処理 (数万ポイント生成等) を毎クック実行している場合は、ジオメトリ更新が必要なフレームだけ Active 制御するか Cache SOP で結果をキャッシュ
  • Python 内で参照している外部オペレータ・パラメータ数を減らす — Script SOP は参照先が変わるたびに再 cook されるため、依存先が多いほどクック頻度が増える
  • 重い数値計算は CPlusPlus SOP や GPU 側 (TOP / POP) に移譲し、Script SOP はパイプラインの薄い接着剤に留める

❌ Problem: 複数入力からのジオメトリ合成で点や色がズレる
✅ Solution:

  • scriptOP.inputs がリストとして 0 個以上の入力を返すことを前提に、for inp in scriptOP.inputs: で安全にイテレート (固定 index 参照は入力 0 個ケースで例外)
  • 各入力のポイント座標 inp.points[i].P をコピーする際は、必要に応じて Transform SOP で事前に正規化座標系を揃える
  • Cd 等のカスタム属性を scriptOP.appendCustomAttribute('Cd', 'vector') で確保してから書き込みしているか — 属性宣言なしの代入は無視される

参考資料 📚

その他 🔗

公式リソース 📖

この記事はLLMと共に内容を執筆、更新しています。
最新バージョンとの項目差異など、情報の不一致を見つけた心優しい方はXもしくはInsta、メールなどよりサイト管理者までご連絡ください😎


まる。

お仕事のご依頼はDM又はメールにて。
━━━━━━━━━━━━━━━━━
Python/Touchdesigner/M5Stackをこよなく愛すフルスタックエンジニア。
専門は生理心理学、趣味はヨガやサウナ、EMS電気風呂などヘルスケア全般。
脳波や筋電、心拍を中心とした生体情報のセンシング&インタラクティブアートづくりがライフワーク。

普段はワントゥーテンという会社で空間演出エンジニアをしています。
リファラル採用お繋ぎできますので、我こそはという尖った方は経歴と希望職種添えてDMください(エンジニア以外、営業職等もOK)。
ご飯行きましょう。

↓日常垢
Instagram:@malmal0v0

まる。をフォローする
その他の記事はこちら
Math Combine POP 完全ガイド | 使い方・パラメータ解説【TouchDesigner】
ZED Select TOP 完全ガイド | 使い方・パラメータ解説【TouchDesigner】
ZED POP 完全ガイド | 使い方・パラメータ解説【TouchDesigner】
Window COMP 完全ガイド | 使い方・パラメータ解説【TouchDesigner】
Widget COMP 完全ガイド | 使い方・パラメータ解説【TouchDesigner】

タイトルとURLをコピーしました