Tscript

From TouchDesigner 099 Wiki

Tscript Command Help

Tscript Expression Help

TouchDesigner Scripting Language

Tscript is TouchDesigner's original built in Scripting language, now alongside the Python language.

Tscript is similar to C-Shell in its syntax and structure. For an overview, read Scripting.

TouchDesigner's Expression language is also used heavily in Tscript. As a result, when learning Tscript, don't focus solely on Tscript itself, but always look at Expressions too.

Commands and Expressions is a complete reference of Tscript.

The Order of Expansion

Expansion of a TouchDesigner command follows the C-shell expansion standards very closely. There are some subtle differences.

Lexical Structure

TouchDesigner splits input lines into words at space characters, except as noted below. The characters ; < > ( ) = form separate words and TouchDesigner will insert spaces around these characters except as noted below. By preceding a special character by a backslash (\), its special meaning can be suppressed.

Evaluation of Quotes

Strings enclosed in a matched pair of quotes forms a partial word. Within double quotes ("), expansion will occur. Within single quotes (') expansion will not be done. Within back-quotes (`) the enclosed string will be evaluated as a TouchDesigner expression and the result will be considered to be a partial word. Inside a matched pair of quotes, the quote character may be protected by preceding the slash with a backslash.

Backquotes are evaluated with a higher priority than double quotes. This means that if a double-quoted argument encloses a back-quoted string, the back-quoted string may contain double quotes without terminating the initial double quote delimiter. For example, the string:

foo'ch("/obj/geo1/tx")'

will be parsed as a single argument.

Note: As a general rule, do not include spaces between your "back" quotation marks and what lies between them. TouchDesigner may not evaluate them if there are extra spaces.

Comments

The character # introduces a comment which continues to the end of the line. This character can be protected by a backslash (\) or by enclosing the character in quotes.

Multiple Commands

Multiple commands can be specified on the same line by separating them with semicolons (;).

Expansion

Expansion is done in the following order: History substitution, Macro expansion, Variable & Expression expansion.

History substitution is not as sophisticated as the csh history mechanism. The supported substitutions are:

  • !! - Repeat last command
  • !str - Repeat last command matching str
  • !num - Repeat command "num" from the history list
  • !-5 - Repeat the command run five commands previous

With the !! substitution, characters following the !! are appended to the command. The resulting command is displayed in the Textport before the command is run.

Variable and expression evaluation are done at the same time and have equal precedence. Variables are delimited by a dollar sign ($) followed by the variable name. A variable name must begin with letter or an underscore (_) followed by any number of letters, numbers or underscores. As well, the variable name may be delimited by curly braces ({}) in which case the contents of the curly braces is expanded before the variable name is resolved. This allows for pseudo array operations on variables.

For example:

touch -> set foo1 = bob 
touch -> set foo2 = sue 
touch -> for i = 1 to 2 
> echo ${foo${i}} 
> end 
bob 
sue 

Expression evaluation is done on the string contained within matching backquotes ( ` ). Inside the backquotes, expression expansion is performed as opposed to command line expansion. The expression is evaluated, and the resulting string is used to replace the expression on the command line. If the expression evaluates to a type other than a string, the result is cast to a string and this is the value used.

Command Expressions

These differ from general TouchDesigner expressions, though TouchDesigner expressions can be used inside of command expressions. The command expressions are used in the "while" and "if" commands. The order of operations in a command expression is as follows:

  • () - Parentheses
  • == != < > <= >= - Equal, Not Equal, Less Than, Greater Than, Less Than or Equal, Greater Than or Equal
  • && || - Logical AND and Logical OR

Expressions can be enclosed in parentheses for clarity, but this is not necessary.

Variables

There are many types of Variables in TouchDesigner. Script variables are variables that are set within a script using the set command. They are local to the script and exist only for the duration of the script. When the script terminates, these variables will automatically be unset.

All variables created by loops are considered local script variables (i.e. the "for" loop will use script variables).

Pattern Matching

Many CHOPs allow patterns to specify multiple channels to be selected or acted upon. These patterns allow wild cards which will match all or parts of strings. Patterns are also used in various Python methods such as ops(), to allow specifying more than one OP by a single string.

  • * - Match any sequence of characters
  • ? - Match any single character
  • ^ - Do not match.
  • [alphaset] - Match any one of alphabetic characters enclosed in the square brackets. In TouchDesigner, the [a-g] format is not currently supported, the characters must be listed as [abcdefg].
  • [num1-num2] or [num1-num2:increment] - Match any integer numbers enclosed in the number range, with the optional increment.
  • [num1,num2,num3] - Match the specific integers given.
  • @groupname - Expands all the items in the group. Since each group belongs to a network, you can specify a path before the @groupname identifier.

NOTE: The opposite of pattern matching is Pattern Expansion, takes a short string and generates a longer string from it.

Pattern matching is also often used to match channel names. It uses the following kinds of patterns to select existing channels in an input CHOP, used in CHOPs like the Select CHOP and the Math CHOP's Scope parameter, where you only want to affect certain channels and leave the reset as-is.

Pattern matching is used to match object names in the Render TOP, and OPs/channel names in the Select CHOP.

Examples

chan2 Matches a single channel name
chan3 tx ty tz Matches four channel names, separated by spaces
chan* Matches each channel that starts with "chan" and ends with anything
*foot* Matches each channel that has "foot" in it, with anything or nothing before or after
t? The ? matches a single character. t? matches two-character channels starting with t, like the translate channels tx, ty and tz
r[xyz] Matches channels rx, ry and rz. that is, "r" followed by any character between the [ ]
blend[3-7:2] Matches number ranges giving blend3, blend5, and blend7. (3 to 7 in steps of 2)
blend[2-3,5,13] Matches channels blend2, blend3, blend5, blend13
t[uvwxyz] [uvwxyz] matches characters between u and z, giving channels tu, tv, tw, tx, ty and tz

See Also

Command Loops

There are three different looping constructs in Tscript:

for

for variable = start to end [step increment] 
... 
end 

foreach

foreach variable ( element_list ) 
... 
end 

while

while ( expression ) 
... 
end 

The for loop will loop from the start, up to and including the end.

The foreach loop will cycle through every element in the element_list assigning the variable value to be a different element each iteration through the loop.

All variables in the for and foreach loops are local variables. To export the variable to other scripts simply set a global variable using the rvar Command or the cvar Command inside the loop.

Example

You can use a loop to perform repetitive tasks for you. For example, if you wanted to wanted to merge 255 SOPs, it would be faster to write a short script than to do all that wiring manually.

For example, if you named your SOPs consistently, like: model_0, model_1, model_2... model_255, then you could execute the following script in a Textport:

for i = 0 to 255 
opwire model_$i -$i merge1 
end 

If you haven't been consistent with naming, you could also do it with a foreach.

Terminating a Long or Endless Script

If TouchDesigner looks like it is hanging, you may have scripted an endless loop by mistake and may want to kill the script. In this case, you can hit Ctrl-Break to interrupt, halt and terminate script execution. It may take a few seconds for TouchDesigner to respond, break from the script and stop processing. You can view messages on which scripts were stopped in the Textport.

Conditional Statements

The "if" command provides the ability for a script to check a condition and then execute one set of commands if the condition is true or an alternate set of commands if the condition is false. It should have an endif to signify the end.

if ( expr ) [then] 
... 
else if (expr2) [then] 
... 
else 
... 
endif

Arithmetic Expressions

Arithmetic Operations

^ - not
+ - add
- - subtract
* - multiply
/ - divide
% - mod


Logical Operations

== - equal to
!= - not equal to
<  - less than
<= - less than or equal to
>  - greater than
>= - greater than or equal to
&& = AND
|| = OR
!  = NOT

Macros and Multiple Commands

Some frequently used commands can be represented with a single word, a Macro.

Example

touch-> macro greet echo hello world 
touch-> greet 
hello world 
touch-> macro mine "opset -d off * ; opset -d on geo1" 
touch-> mine 

This will execute the string attached to the macro "mine" and turn off the display of all the objects then turn on object geo1.

The next two commands list, then undefine, a macro:

touch-> macro 
greet hello world 
mine opset -d off * ; opset -d on geo1 
touch-> macro -u greet 

TouchDesigner accepts several commands on the same command line separated by a semicolon ( ; ). This does not apply to semicolons embedded in quotes. Macros can contain commands embedded in quotes.

Redirecting Command Output to DATs

Redirect to a DAT (clearing the DAT first) with the echo Command:

echo "abc" > text1

appending a line to the DAT:

echo "abc" >> text1

If the DAT does not exist, TouchDesigner will create a Text DAT and place the new text in it.

It doesn't matter if there is a space after the > or >>.

You can append to a pre-existing table, which adds a new row to the table.

There are two syntax forms to put things in different columns. First by putting \t in your text string:

echo abc\tdef\tghi >> table1

and with quotes around it you need to put actual tab characters in the string:

echo "abc   def  ghi" >> table1

where the spaces above are actual tab characters (not \t).

Redirecting Command Output to Files

To redirect the output to a file in the filesystem, use FILE: as a destination prefix. Examples:

echo "hello world" > FILE:abc.txt          # relative to current disk folder on current drive
echo "hello world" > FILE:Map/README.txt   # relative path, into subfolder Map
echo "hello world" > FILE:C:/abc.txt       # absolute path
echo "hello world" > FILE:$TOUCH/test.txt  # new file using Built-in Variable for the path to your project.
echo "hello world" >> FILE:$TOUCH/test.txt # this appends text

Note the quotes are optional in the above examples. Also note >> can be used to append to existing text, instead of replacing it. If no prefix is given, a DAT node path is assumed. This can also be specified with the DAT: prefix, though this is redundant.

Using Arguments in Scripts

When calling a script with run Command or include Command, arguments can be passed to the script. These arguments are set to TouchDesigner script variables so that they can be used by the script.

Example Assuming the current TouchDesigner component contains repeatscript (see pc and cc):

touch-> run repeatscript 1 10 2 blockhead

where repeatscript contains:

echo Hello, my name is $arg4 
for i = $arg1 to $arg2 step $arg3 
echo I said, my name is $arg4 
end 

Note that there are four variables in the script: arg1, arg2, arg3 and arg4. These are set to the arguments 1, 10, 2 and blockhead respectively.

  • $arg0 - name of the script

You can get the name of the script being run from $arg0.

For example: run myscript 1 4.5 7 balloon will come into the script with

  • $argc = 5
  • $arg0 = myscript
  • $arg1 = 1
  • $arg2 = 4.5
  • $arg3 = 7
  • $arg4 = balloon

This allows usages such as:

if $argc != 5 then 
echo USAGE: cmdread $arg0 numclowns clownsize numtoys toytype 
exit 
endif 
  • $argc - number of arguments passed to script

The number of arguments passed to the script can be retrieved with the variable $argc.

For example, from the lookat script:

# USAGE: lookat eyeobject focusobject 
if $argc!= 2 then 
echo USAGE: source lookat eyeobject focusobject 
exit 
endif

Examples

Question: How would I get all the container level parameters of the master component and reapply them to a clone?

 set master = $arg1 
 set clone = $arg2
 opparm $clone `run("parmls /$master")`

The problem is that you will loose spaces, so any par("tx") will end up as par(tx), which produces an error. The following script seems to work better, but hasn't been tested very much.

 set master = $arg1 
 set clone = $arg2
 foreach p (`noevals(run("parmls $master"))`)
    if (`arg("$p",1)` !="")
       opparm $clone $p
    else
       opparm $op `arg("$p",0)` ""
    endif
    print ""
  end