scriptDAT | Tips and Tricks | TouchDesigner

If you spend lots of time setting up parameters in your UI elements and want a faster way to use a set of presets to populate some parameters, then the Script DAT might be just what you’re looking for.

Let’s look at a fast simple example that might have you re-thinking how to quickly set up pars in a project. Keep in mind that this won’t work in every situation, but it might work for an awful lot of them and in ways that you might not have expected.

To get started let us imagine that we have a simple set-up where we have a UI element and a display element. We want a fast way to quickly update their parameters. For the sake of this example let’s imagine that we do not need any fancy scaling or changes on the fly. This is going to be used on a set of displays where we know exactly how they’re going to display. We might think about using storage to set and pull parameters, but you might be hesitant to use too much python for those bits and bobs. Okay, so exports it is… they’re a little more cumbersome to set up, but they are much faster – fine.

Sigh.

I guess we need to start setting up an export table, or a constant CHOP and dragging and dropping all over creation. Before you do that though, take a closer look that is the majesty of the Script DAT:

The Script DAT runs a script each time the DAT cooks and can build/modify the output table based in the optional input tables. The Script DAT is created with a docked (attached) DAT that contains three Python methods: cook, onPulse, and setupParameters. The cook method is run each time the Script DAT cooks. The setupParameters method is run whenever the Setup Parameter button on the Script page is pressed. The onPulse method is run whenever a custom pulse parameter is pushed.

Maybe we can use the Script DAT to make an export table for us with just a little bit of python.

We can start by putting a few things into storage. Let’s create a new dictionary but follow some simple rules:

  • The keys in this dictionary are going to be operator names or paths
  • Each operator is itself a key for another dictionary
  • The keys of that dictionary must be proper parameter names
  • The values associated with these keys need to be legal entries for parameters

Okay, with these rules in mind let’s see what we can do. Open up a new project, in project1 let’s create two new containers:

  • container_ui
  • continer_led_display

Add a new text DAT and create a simple dictionary to put into storage, and let’s follow the rules we described above:

# it's important here to know that 
# pars need to match their correct
# parameter name in order for this to
# work correctly.

# in that same vein, the relative paths
# are based on the location of the script
# op that's being used

# finally, for this to work correctly, you'll
# need to re-run this dat in order to place
# new values into storage

attr = {
    "container_ui" :{ 
        "w" : 500,
        "h" : 1080,
        "alignorder" : 0
    },
    "container_led_display": {
        "w" : 400,
        "h" : 300,
        "alignorder" : 1
    },
    "..":{
        "align" : 1,
        "justifyv" : 1
    }
}

parent().store( 'set_up_attr', attr )

Alright, so far so good. Now let’s add a Script DAT.

We’re going to use our Script DAT to look at our stored vals and create an export table on the fly for whatever is in the storage dictionary “attr” – easy.

Let’s edit our Script DAT to have the following contents:

# me - this DAT
# scriptOp - the OP which is cooking
#
# press 'Setup Parameters' in the OP to call this function to re-create the parameters.

# define where pars is coming from
pars = parent().fetch( 'set_up_attr' )

def setupParameters(scriptOp):
    return

# called whenever custom pulse parameter is pushed
def onPulse(par):
    return

def cook(scriptOp):
    scriptOp.clear()

    # insert header row
    scriptOp.insertRow( [ 'path', 'parameter', 'value', 'enable' ] )

    # loop through dictionary for pars
    for key, value in pars.items():
        for item_key, item_value in value.items():
            scriptOp.appendRow( [ key, item_key, item_value, 1 ] )

    # set up parent pars for heigh and width
    parent_height = max( [ pars[ 'container_ui' ][ 'h' ], pars[ 'container_led_display' ][ 'h' ] ] )
    parent_width = sum( [ pars[ 'container_ui' ][ 'w' ], pars[ 'container_led_display' ][ 'w' ] ] )
    scriptOp.appendRow( [ '..', 'w', parent_width, 1 ] )
    scriptOp.appendRow( [ '..', 'h', parent_height, 1 ] )

return

Finally, let’s turn on the green export flag at the bottom of our Script DAT:

script_dat.PNG

And just like that we’ve set-up an auto-export system. Now every time we update our dictionary run our script to put the contents into storage we’ll automatically push those changes to an export table.

Looking for an example to pull apart – head over to github and download a simple example to look over.

Cellular Noise

A post shared by Matthew Ragan (@raganmd) on

 

A post shared by Matthew Ragan (@raganmd) on

 

Practice your vertex shaders

A post shared by Matthew Ragan (@raganmd) on

 

A post shared by Matthew Ragan (@raganmd) on

 

A post shared by Matthew Ragan (@raganmd) on

 

A post shared by Matthew Ragan (@raganmd) on

 

A post shared by Matthew Ragan (@raganmd) on