Working with OPs in Python

From Derivative
Jump to: navigation, search

The main class type describing any Operator is the base OP Class. You will need a reference to one of these to do anything. There are two global operator objects are always available (except for in the Textport):

  • me refers to the operator that is currently being evaluated or executed. For example, when executing a script, me refers to the containing DAT. When evaluating an expression, me refers to the containing operator.
  • root refers to the top level component /.

To get references to other OPs (for example, a node named 'wave1' sitting next to the node 'constant1') the most common functions to use are: op() and ops(), for example op('wave1').

op() returns a single OP object, while ops returns a (possibly empty) list of OPs. They are described in td Module.

These functions search for operators from the current component, so both relative and absolute paths are supported. The current component is defined as: The OP that me is inside.

Note that the OP Class itself, also contains an op() and ops() method. In this case, nodes are searched from the OP.

For example: me.op('..') will always return its own parent, while op('..') will return the parent of the current component.

If you are typing a python expression in a parameter of a node 'constant1', and you wish to get a reference to 'wave1', you would type

 op('wave1')

If you are in a script you can assign this reference to a variable for easier repeated access.

 n = op('wave1')

In this case op() will search relative to the DAT that is executing the script.

An OP also has a parent() method that can be use to get the parent COMP of it.

 me.parent()

If you are putting a Python statement in a parameter of a COMP and want to refer to a child of that COMP, you can use the op() method for the OP, which is available as me in the parameters.

 me.op('achildnode')

TIP: To find out quickly what members and methods you have access to for any node, select that node and on its parameter dialog, click the Python Help icon. You will go the wiki for the python classes for that node. There you can find out what info you can get about a node, and what methods are available for it. The documentation can also be arrived at by right clicking on the node and selecting "Python Help..." from the menu.


Examples[edit]

Place down a new Text DAT, ensure its parameter flag is set to Python, and enter the following script:

n = op('/project1')
m = n.ops('text*')
for a in m:
    print(a.name)

After running the script, n is assigned the results of the global function, while m is assigned results relative to n.

Some useful members and methods of an OP object, are:

  • name
  • path
  • children
  • parent()

These are described in OP Class. Notice the last attribute, parent() is a function. It takes an optional argument specifying how far up the parent chain to climb. To see how they are used in practice, put down a new Text DAT, ensure its Parameter Language parameter is set to Python and enter the following code:

print('i am ', me)
print('child of ', me.parent())
print('grandchild of ', me.parent(2))

print('root children:')
k = root.children
for r in k:
    print(r)

The resulting details will be found in the textport.


Python - TScript Equivalents[edit]

Commands[edit]

Python TScript
Creating an OP (Sphere SOP) op('/project1').create(sphereSOP) cc /project1
opadd SOP:sphere
Creating a named OP op('/project1').create(sphereSOP, 'mysphere') cc /project1
opadd SOP:sphere "mysphere"
Copying OPs (Nodes) op('/project1').copy(op('out1'), 'out2') opcp /project1/out1 out2
Deleting an OP op('mysphere').destroy() cc /project1
oprm "mysphere"
Renaming an OP op('mysphere').name = 'thesphere' cc /project1
opname "mysphere" "thesphere"
Changing an OP's type op('mysphere').changeType(boxSOP) cc /project1
opchangetype "mysphere" SOP:box
Changing multiple OPs' types list = ops('*sphere*')
[s.changeType(boxSOP) for s in list]
cc /project1
opchangetype "*sphere*" SOP:box
Setting an OP's comment op('mysphere').comment = 'this is a sphere' cc /project1
opcomment -c "this is a sphere" "mysphere"
Changing an OP's parameter op('mysphere').par.frequency = 10 cc /project1
opparm "mysphere" frequency ( 10 )
Changing an OP's parameter
with more than 1 value
s = op('mysphere')
s.par.tx = 1
s.par.ty = 2
s.par.tz = 3
cc /project1
opparm "mysphere" t( 1 2 3 )
Pulsing a parameter value op('moviein1').par.cue.pulse() opparm -p moviein1 cue (1)
Cooking an OP op('mysphere').cook() cc /project1
opcook "mysphere"
Saving an OP's data to a file op('mysphere').save('sphere.tog') cc /project1
opsave "mysphere" "sphere.tog"
Changing an OP's Render and Display Flags on s = op('mysphere')
s.render = True
s.display = True
cc /project1
opset -r 1 -d 1 "mysphere"
Loading a .tox file into a COMP op('/project1').loadTox('geo1.tox') cc /project1
loadcomponent "geo1.tox"
Wiring operators together Refer to the Connector Class opwire command
Clicking gadgets (panel components) op('slider1').click(.6, .7) click slider1 .6 .7
Timeline Play/Pause me.time.play = True/False playback/playback -s

Expressions[edit]

Python TScript
Querying another OP's parameter op('sphere1').par.tx par("sphere1:tx")
Querying a parameter in the same OP me.par.tx par("tx")
Getting Info CHOP channels from an OP
without cooking it
passive(op('moviein1')).width opinfop("moviein1", "resx")
Getting an OP's parent parent() opparent(".", 0)
Getting an OP's grand-parent parent(2) opparent(".", 1)
Getting an OP's name me.name $ON
Getting an OP's parent's name parent().name $OPN
Getting digits of an OP's name in its parameters me.digits $OD
Getting digits of an OP's parent's
name in its parameters
parent().digits $OPD
Getting digits of another OP's name op("moviein1").digits opdigits("moviein1")
Getting an OP's type # returns an op object, not a string
type(op('moviein1'))
optype("moviein1")
getting a unique random number each frame tdu.rand(absTime.frame+.1) rand($AF+.1)
getting a unique random number per numbered operator tdu.rand(me.digits+.17) rand($OD+.1)
Checking for an OP's existence if op('moviein1'):

or

bool(op('moviein1'))

opexists('moviein1')
Getting the number of children of a COMP len(op('geo1').children) opnumchildren("geo1")
Getting the number of inputs of a multi-input OP len(op('switch1').inputs)
Getting Info CHOP channels from an OP, width is a member op('moviein1').width opinfo("moviein1", "resx")
Conditional "if" in one line of a parameter 22 if me.time.frame<100 else 33 if($F<100,22,33)
Conditional "if" alternative [33,22][me.time.frame<100] if($F<100,22,33)

Time[edit]

"Absolute Time" is the time since you started your TouchDesigner process, not counting when your power button was off (top bar).

Python TScript
Retrieving a node's local frame number me.time.frame $F
Retrieving a node's local time in seconds me.time.seconds $T
Retrieving absolute time in frames absTime.frame $AF
Retrieving absolute time in seconds absTime.seconds $AT

Storage in Python[edit]

Storage is the preferred way to work with persistent global data in Python, since it can store anything data type.

Python
Setting a value in storage of a component n n.store('keyname', 0.0)
Getting a value from storage n.fetch('keyname')

Variables[edit]

Variables are always text strings.

Python TScript
Setting a value me.var('DESKTOP') $DESKTOP
Setting a Root Variable root.setVar('MEDIA', 'c:/MEDIA') rvar MEDIA="c:/MEDIA"
Setting a Component Variable
at the current component
parent().setVar('MEDIA', 'c:/MEDIA') cvar MEDIA="c:/MEDIA"
Setting a Component Variable
at another component
op('/project1/geo1').setVar('MEDIA', 'c:/MEDIA') cvar -p "/project1/geo1" MEDIA="c:/MEDIA"
Setting a Path Variable Set the Path Variable parameter of any parent component and use me.var('name') in the same way. Set the Path Variable parameter of any parent component.


A dialog box in which commands and scripts can entered manually. Script errors and python print() messages are also output to the textport.

An Operator Family that manipulates text strings: multi-line text or tables. Multi-line text is often a command Script, but can be any multi-line text. Tables are rows and columns of cells, each containing a text string.

Any of the procedural data operators. OPs do all the work in TouchDesigner. They "cook" and output data to other OPs, which ultimately result in new images, data and audio being generated. See Node.

An Operator Family that contains its own Network inside. There are twelve 3D Object Component and eight 2D Panel Component types. See also Network Path.

An Operator Family that reads, creates and modifies 3D polygons, curves, NURBS surfaces, spheres, meatballs and other 3D surface data.

TouchDesigner Component file, the file type used to save a Component from TouchDesigner.

The panel at the bottom of TouchDesigner, it controls the current Time of the full system or just one component.

An Operator Family which operate on Channels (a series of numbers) which are used for animation, audio, mathematics, simulation, logic, UI construction, and many other applications.

Storage is a python dictionary associated with any operator, used to keep user-specified data within the operator.

An Operator Family that contains its own Network inside. There are twelve 3D Object Component and eight 2D Panel Component types. See also Network Path.

The location of an operator within the TouchDesigner environment, for example, /geo1/torus1, a node called torus1 in a component called geo1. The path / is called Root. To refer instead to a filesystem folder, directory, disk file or http: address, see Folder.