Tag Archives: TouchDesigner Tutorial

TouchDesigner | Getting More out of the CHOP Execute DAT

One of the most challenging elements for me to wrap my heard around when using TouchDesigner was the Execute DATs. When scripting was still new to me, it was hard to understand where to start, or what to write. It was also hard to understand what kind of options I had when dealing with the execute family of DATs. Let’s take a closer look at some of the interesting elements that you can extract from a CHOP Execute DAT, and hopefully learn a few things along the way.
LFO Trail

CHOP Execute DATs allow us to run a script at particular events. The functions that you see in the CHOP Execute specify what kind of event, and what kind of information gets passed into those events that you might take advantage of. Looking at the CHOP Execute DAT we can see the following kinds of events that we might want to take advantage of:

  • Off to On
  • While On
  • On to Off
  • While Off
  • Value Change


That’s all well and good, but what do those things actually mean? Let’s create a simple script to see what we end up with. We’ll work mostly with the Off to On Definition – with what we learn here you can start to explore what the other definitions do (when I say definitions, I’m mean the portions of the Execute DAT that begin with def).

Before we can get started we need a CHOP in our network to associate with our CHOP Execute DAT. Let’s add an LFO CHOP, and a CHOP Execute DAT to our network.


Next we need to associate our CHOP with our DAT. We can do this by dragging the LFO CHOP onto the CHOP Execute DAT.

associate CHOP to DAT

Next we need to make sure that in the parameters of our Execute DAT that the flag which corresponds to our definition is turned on.

Screenshot_061015_114629_PMWith my default values, I can see that something isn’t quite right. Here my “Value Change” Flag is turned on, I want to turn off that flag and turn on the Off to On Flag. The parameters for your CHOP Execute should now look like this:


Alright, now that we’re just about set up let’s see what happens when we write some scripts for our Execute DAT. The simplest place for us to start might be to just print a string. Let’s add this line to inside of our definition:

print('Hello World')

Because this is inside of a defined function, we’ll also need to make sure that it’s indented. The whole function should look like this in your DAT:

def offToOn(channel, sampleIndex, val, prev):
    print('Hello World')

In TouchDesigner that looks like this:


That’s all well and good, but what does that do? Well, if we open up our text port we should see that ever time we cross the 0 threshold in our LFO that we print “Hello World” to the text port.

Hello World

That in itself isn’t very excited, but we might imagine a situation where we want to run a script at a given regular interval, and this is exactly the kind of technique we might use to make that happen. You might also notice that there are several other parameters for this function that we might be interested in.

Before we get in too deep, lets remember to read what’s already in our DAT. We can see that the header comment reads:

# me is this DAT.
# channel is the Channel object which has changed.
# sampleIndex is the index of the changed sample
# val is the numeric value of the changed sample.
# prev is the previous sample value.
# Make sure the corresponding toggle is enabled in the CHOP Execute DAT.

In general I like to think about any scripting with the following kind of mantra – “When in Doubt, Print it Out.” With that in mind, let’s just print out these parameters to see what they are. To do that, we’ll change our function to read like the following:

def offToOn(channel, sampleIndex, val, prev):
    print('channel is ' , channel)
    print('sampleIndex is ', sampleIndex)
    print('val is ', val)
    print('prev is ', prev)

The results in our text port should look something like this:


This should give us a sense of the kinds of information that we can pull out of our Panel Execute DAT. Before we stop, let’s push a little harder on one of these ideas. First we need to make some changes to our LFO. Let’s first use some pattern matching to add some more channels. We can do this on the Channel Page of our CHOP by specifying that our Channel Names should be chan[1-5]:

Screenshot_061115_122708_AMNext, lets give these unique all a unique phase with the following python expression:



Alright, now we should have an LFO that looks something like this:


Let’s change up our Execute DAT to see what kinds of interesting information we might be able to extract from this. First let’s just see if we can retrieve the channel index as our wave passes through zero. We can do this by changing our function to read:

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

In TouchDesigner that might look like this:

Screenshot_061115_123416_AMThat’s pretty interesting, but what if we only want to print out a line of text when a certain set of conditions are met? We might imagine a scenery where we want to first match a logical test, then run a script.

Let’s try writing something like this:

def offToOn(channel, sampleIndex, val, prev):
    if channel.index == 0:
        print('This will only appear when index 0 fires')
    if channel.index == 1:
        print('This will only appear when index 1 fires')
    if channel.index == 2:
        print('This will only appear when index 2 fires')
    if channel.index == 3:
        print('This will only appear when index 3 fires')
    if channel.index == 4:
        print('This will only appear when index 4 fires')

We’ve now set up a series of tests where we’ll only see a particular line of text when the if conditions are met. As a result we should see this in the text port:


This may initially seem unimpressive, but when you begin to imagine how you might combine the power of CHOPs with the extensible nature of scripting you soon end up with a world of options that wasn’t present before.

Looking for the Example Files? You can find them here on GitHub.

TouchDesigner | Make a Copy of that Table

When working with DATs there are often a whole host of operations that we want to be able to take advantage of that don’t make sense when we initially look at the documentation on the TouchDesigner Wiki. One simple example of this is how copy operations work. A clear example of this might be how copy operations work. For example, I have a table full of information but I’d like to make a copy of it for another part of my network. If we look at the Table DAT Class wiki page we see this:


Copy the text or table from the specified DAT operator.

  • OP – The DAT operator whose contents should be copied into the DAT.

How can we make sense of this?

Let’s start by first setting up a simple table – you can fill it with any information that you’d like. We also want an empty Table DAT, as well as a Text DAT.


In our Text DAT we’re going to write the following script:

source = op('table1')
target = op('table2')


Looking at the syntax of the operation we can see what we first defined two variables – target and source, named as such to make it easier to see what’s happening. Next we start with the target and then specify what operator we’d like to copy. Now we can right click on the text DAT, run our script, and voila. A little copy magic.

anatomy of a copy script

Need to see it action? Look through the example files on Git Hub.

TouchDesigner | Drop Scripts

We all love some drag and drop action – we use it all the time, and in fact have often come to expect it to be a feature in nearly every application we interact with. With that in mind, how can we think about integrating some drop actions into our work in TouchDesigner? Well, today is your lucky day! Here we’re going to look at some of the fundamental ideas that will help you get started with much more complicated drag and drop functions.

Anatomy of a Drop Script

Let’s start by setting up a container to perform some actions based on when we drop a file onto it – this will help us get our bearings, and see how dropping works. First we need to set up our container to work with a drop script. First add a new container to a network, next let’s go to the Drag page of the container, and look at the sub page labeled “On Dropping into this Component.”


We’ll start by first changing the drop down menu here to be “Allow Drop.” Next we’ll need to specify what script to run when something is dropped onto this Component. Let’s plan to call our script dropScript, and we’ll place it inside of our container. This means that we can specify it’s relative path and name as


Now we should have something that looks like this:


Now we’re ready to start working. First let’s navigate inside of our container, then split our work-space left and right, and open up a text port on one side of our work-space. Inside of container1 let’s add a new Text DAT and call it dropScript – just like we had planed earlier.


To get started, let’s first write a simple script so we can see this whole thing in action. In our Text DAT let’s use the simple script:

print('Hello World')


To this in action, let’s open the viewer for our container and drop a file onto it – we’ll want to keep an eye on our text port as well, because this is where our print command will show up.


Perfect. Here we can see that when we drop something onto our container, low and behold our script runs. This is great, but wouldn’t it be slick if we could instead get the pathway to our file? In fact, we can get this! Let’s change out drop script to this:

print( args )

Now when we drop something on to our container we get a list that should look something like this:

('E:/Dropbox/Camera Uploads/2015-05-26 10.55.18.jpg', '0', '0', '0', '1', 'jpg', '2015-05-26 10.55.18', '/container1')

The first item in this list is what we’re looking for – it’s the pathway to where our dropped file lives on our computer. Let’s change our drop script so we only get that first item in our list.

print( args[0] )

Now when we drop a file onto our container we only get the pathway to the file.


That’s all well and good, but what can we do with that?

Changing a Movie File In TOP

Let’s set up a few other items in our container so we can really see this in action. Let’s add a Movie File In TOP, wire that to a Fit TOP, and finally to a Null TOP.


Set the Fit TOP resolution to match that parent container with following expressions:



Finally, let’s name the null bg, and set the parent to display this as the background TOP.


Now we’re ready to return to our drop script. Let’s change our drop script to set the parameter “file” on the Movie File In TOP to be the path from args. In python that looks something like this:

op('moviefilein1').par.file = args[0]

If you’re following along at home, you might want to consider adding some comments and breaking this up slightly. It may make your code a little more verbose, but when you come back to it later on it will be easier to decode what’s actually going on here. That might end up reading like this:

# identify the movie file in 
# operator that I want to change
movTarget = op('moviefilein1')

# make a new variable called newFile
# assign the args[0] string to this variable
newFile = args[0]

# set the file paramater for the target op
# to be newFile - this means that when I drop
# an image onto this container, that file
# will become the background
movTarget.par.file = newFile

Commenting isn’t always the most fun part of programming, but when you come back to a project or script it can make it much easier to remember what you were thinking and how you were working.

Now, when we drop a file onto our container, we should see the background file change as well.


Changing a Directory

That’s great, but how can we push this a little farther? Well, we might imagine that we find ourselves in a situation where we’d like to change the target directory for a Folder DAT. While the Choose a Directory example works well, it you might not want the hassle of navigating to your folder – instead you might just want to drop it onto your container. We can use the same principles from above to do just that.

Let’s add a Folder DAT to our network. Now we’ll change our dropScript to be:

folderDAT = op('folder1')
folderDAT.par.rootfolder = args[0]

Now we can drag an entire folder onto our container and see the Folder DAT update.


Bada bing! With a few basics under your belt, now you can have fun and and start to play with doing something exciting with drop scripts.

Want to take a look at some examples? You can find them here on GitHub

THP 494 & 598 | Touch OSC – A Case Study | TouchDesigner

Core Concepts

  • Hexler’s Touch OSC
  • Simple Network Communication with Open Sound Control
  • Sending Floats from TouchOSC to TouchDesigner
  • Sending Floats from TouchDesigner to TouchOSC
  • Sending Messages from TouchDesiger to TouchOSC