Skip to content

TouchDesigner

TouchDesigner is a node-based visual development platform providing a low-code environment for the development of real-time interactive media experiences. The software can generate real-time 3D graphics, perform compositing and projection mapping, interact with musical devices using MIDI or OSC, interact with lighting systems or microcontrollers like the Arduino, or process data and interact with external APIs using Python programming. The software is commonly used for architectural scale projection mapping, live music visualisations and light shows. It can also be used for prototyping new user interfaces and has support for VR. TouchDesigner can be used on computers running either Windows or MacOS.

Personal Experience

I've used TouchDesigner to create data overlays for the Data City Dublin exhibit, a 3D printed model of central Dublin with dynamic data projections created for both the Building City Dashboards and Data Stories projects based at Maynooth University in Ireland.

Tools & Software Integrations

N/A

  • ResetPLS - A component by Function.Store which pulses all 'resetpulse' parameters of selected operators from a single switch. The depth of the components search through the TouchDesigner node network can be limited to a specific number.
  • Save External - A simple save external tox and text helper which helps to manage modular projects. The plugin can be downloaded from GitHub: touchdesigner-save-external
  • Stoner - Stoner is a grid-warping and upscale 'keystoner' tool that provides two levels of image warping: a 4-point corner-pin and; a mesh warper where for each point of the mesh can be adjusted using bezier handles. The tool outputs the final warped image and a displacement map which can be used in conjunction with the Remap TOP to store a mapping.
  • UI Theme - A component to style in bulk the basic widgets provided by Touch Designer. With this component you can load and preview the Basic Widgets provided by Touch Designer. It allows you to create a theme that can be applied to the selected widgets or to a selected component containing widgets.

Resources

Notes and Troubleshooting

Operators VS Python

  • Operators (OPs) Pros:
    • TouchDesigner professionals recommend doing as much as possible with because all operators are either C++ or GLSL code with editable parameters. These two languages will generally be faster than Python for raw execution. Hence, crunching numbers and doing signal processing with CHOPs, as the C++ code behind the scenes will generally be faster than writing a Python script to do the same thing.
    • The visual nature of operators mean that you are able to see every step of the pipeline and visually debug a process in the viewer.
    • It’s an expensive process to cross the Python <-> operator bridge and can be processor intensive.
  • Python Pros:
    • It is often much easier to program complex logic in a script than it is to create a network of nodes to perform the same function.
    • In many cases it can be easier and more intuitive to control operators/parameters with Python than it can be with expressions.
    • It can also have optimization benefits to not have Python references to operators active on operators that are cooking every frame if you only need to update the parameter values periodically.
    • Holding large amounts of data and working on it with Python scripts is more performant with Python storage than it is writing all that data to a table DAT and retrieving it from there.
    • Developers increasingly use Python Extensions to extend a components functionality and data because it is easier to manage and and work with programmatically. When working in this way it can make sense to stay inside Python.

Source: Python vs TouchDesigner Operators

Python Coding in TouchDesigner

Accessing Objects in Python

Accessing TouchDesigner objects through Python to call an op() search or update a parameter can be slow. This can be addressed by reducing op() calls and searches by storing a reference to the operators parameter class so you only need access it once:

some_op = op('some_op').par
a = some_op.value0
b = some_op.value1
c = some_op.value2

Source: Python Optimization in TouchDesigner

Enabling an External Text Editor

Writing Python scripts in DATs can be more efficient when working with an external text editor. To enable an external editor: 1. Open the ’Preferences’ dialog found in the ’Edit’ menu. 2. Go to the ’DATs’ preferences.
3. Click the file browser icon for the ’Text Editor’ setting.
4. Assign the the external editor’s executable (.exe) by selecting it and clicking ’Open’. This is usually located in the ’Program Files’ folder. 5. Click ’Accept’ on the Preferences dialog. 6. Once the setup is complete, right click on a DAT and click the ’Edit Contents’ option. The DAT will be opened in the program which is specified by this preference.

Source: https://nvoid.gitbooks.io/introduction-to-touchdesigner/content/Basics/1-5-Using-an-External-Text-Editor.html

Minimise print() Calls

The longer the TouchDesigner textport log gets, the slower your project will run. Avoid this by keeping track of print statements in your project and turn them off before your final deployment.

Source: Python Optimization in TouchDesigner

Optimising Callbacks

Placing code elements like op() calls in callbacks can be expensive because they will get reinitilised every time values change. Instead place them outside the callback:

# Iniitialise op() calls here
a = op('some_op')
b = op('some_op1')
c = op('some_op2')
d = op('some_op3')

def onOffToOn(channel, sampleIndex, val, prev):
    return

def whileOn(channel, sampleIndex, val, prev):
    return

def onOffToOn(channel, sampleIndex, val, prev):
    return

def onOnToOff(channel, sampleIndex, val, prev):
    return

def whileOff(channel, sampleIndex, val, prev):
    return

def onValueChange(channel, sampleIndex, val,, prev):

    # Reference op() calls with local variables
    a_val = a.par.value0
    b_val = b.par.value0
    c_val = c.par.value0
    d_val = d.par.value0

    if a_val > b_val and c_val > d_val:
        print('hello')
    elif a_val < b_val and c_val < d_val:
        print('nope')

Source: Python Optimization in TouchDesigner

TouchDesigner-Specific Python Utilities

TouchDesigner includes a number of Python utilites which are provided by default and provide useful TouchDesigner-specific functionality: - TDFunctions – This module provides a variety of useful utility functions, which include clamping values within a certain range, iterating strings with digits on the end, arranging nodes in the network, and many more. - TDJSON – A module of utility functions for JSON features in TouchDesigner, which are mainly focused around custom parameters and parameter pages. For example, there are functions that allow conversion of parameters or pages of parameters to JSON, and for adding parameters from JSON files. - TDStoreTools – Module that contains functionality for making Storage easy to use within Python Extensions.

Source: Useful Python Libraries for TouchDesigner Beginners

Using seattr() to Set Operator Parameters

The setattr function can be used to easily update operator parameters in a loop: 1. Create a for loop. 2. Get a reference to our operator. 3. Use setattr by passing it three arguments: setattr(object, name, value) - The object we want to work with. - A string name of an attribute you want to access - The value you want to pass.

# start the for loop
for i in range(10):

    # reference the operator
    update_me = op('constant1')

    # use setattr to set the parameter values
    setattr(update_me.par, 'value{}'.format(i), 9000)

Source: TouchDesigner Python Tricks

Using the Subprocess Module to Avoid Blocking Operations

Python libraries may include functions which involve blocking operations that can make it appear that TouchDesigner has frozen while the whole operation completes. An alternative to using threading is to use the subprocess module which allows you to run a python script as a parallel execution that doesn’t touch your TouchDesigner application:

import subprocess

# point to our script that we're going to execute
cmd_python_script = '{}/scripts/cmd_line_python_udp_msg_args.py'.format(project.folder)

# point to the specific version of python that we want to use
python_exe = 'C:/Program Files/Python35/python.exe'

# construct a list of our python args - which python and which script
python_args = ['python', cmd_python_script]

# construct a list of arguments for out external script
script_args = ['-i', 'Hello', '-i2', 'TouchDesigner']

# join our two lists - python args and scirpt args
cmd_args = python_args + script_args

# call our script with subprocess
subprocess.Popen(cmd_args, shell = True)
  1. Write a separate python script e.g. script.py.
  2. In TouchDesigner add a DAT with Python which will call the external script.
  3. Import subprocess.
  4. Get a reference to the path to the external script.
  5. Optionally specify the path to a specific version of Python to run the script as an additional argument.
  6. Optionally specify arguments to pass to the script.
  7. Call subprocess to run the script.

This process can be extended to receive messages back from the external script e.g. by using UDP mesaging.

Source: TouchDesigner | Python And The Subprocess Module

TouchDesigner Operator Summary

  • COMP - Components are operators that contains their own network of operators. There are 3D object components and 2D panel components amongst a range of others.
  • TOP - Texture Operators can create, read, write, composite and modify 2D images and video. TOPs run on a computer graphics card's GPU.
  • CHOP - Channel Operators work on sequences of numbers or 'channels' that can represent motion, control signals, MIDI, audio, color maps, rolloff curves or lookup tables. They can be used for animation, audio, mathematics, simulation, logic, UI construction, and data streamed from/to devices and protocols.
  • SOP - Surface Operators can read, create and modify geometry and 3D objects like 3D points, polygons, lines, particles, surfaces, spheres and meatballs. However, particles and point clouds are now done primarily on the GPU using TOPs.
  • MAT - Materials are operators that apply a shader to a SOP for rendering textured and lit surfaces.
  • DAT - Data Operators manipulate text strings including multi-line text or tables. Typical multi-line text is often a python script or GLSL shader.
  • Custom - Custom Operators are 3rd party operators that have been created using TouchDesigner's C++ API.