Search is based on keyword.
Ex: "Procedures"
Do not search with natural language
Ex: "How do I write a new procedure?"
AttributeScript to OpScript Conversion
The following Python function examples for AttributeScript have Lua function examples for use with OpScript. This is not an exhaustive list, but may offer a helpful "cheat sheet" for those with AttributeScripts in existing scenes who may wish to convert over to OpScript.
For more information on OpScript, please refer to Working with Attributes, or look at the OpScript tutorials in the Help > Example Projects menu in Katana. For details on the OpScript API, see the OpScript Reference documentation available from the Help > Documentation menu in Katana.
GetAttr
Locally Set Values
Python:
tacoList = GetAttr("taco") # local value if tacoList: tacoSingleValue = tacoList[0] # returns None if not available locally
Lua:
-- local value local tacoAttr = Interface.GetAttr("taco") if tacoAttr then -- Convert to a table/list by calling the getNearestSample method local tacoList = tacoAttr:getNearestSample(0.0) -- First element (Note that Lua table indices start at 1) local tacoSingleValue = tacoList[1] end
If you just want the first value at time 0.0, there's a convenient function for that in Lua:
-- local value local tacoAttr = Interface.GetAttr("taco") if tacoAttr then local tacoSingleValue = tacoAttr:getValue() end
Inherited Values
Python:
# inherited value. GetAttr() returns None if not available globally or locally tacoInheritedList = GetAttr("taco", inherit=True) if tacoInheritedList: tacoInheritedValue = tacoInheritedList[0]
Lua:
-- inherited value local tacoInheritedAttr = Interface.GetGlobalAttr("taco") if tacoInheritedAttr then -- Convert to a table/list by calling getNearestSample() local tacoInheritedList = tacoInheritedAttr:getNearestSample(0.0) -- First index (Note the 1, not the 0) local tacoInheritedValue = tacoInheritedList[1] end
If you just want the first value at time 0.0, there's a convenient method for that in OpScript:
-- inherited value local tacoInheritedAttr = Interface.GetGlobalAttr("taco") if tacoInheritedAttr then local tacoInheritedValue = tacoInheritedAttr:getValue() end
Specifying a Location
Python:
tacoAttrAtLocation = GetAttr('taco', atLocation='/root/whatever')
Lua:
local tacoAttrAtLocation = Interface.GetAttr('taco', '/root/whatever')
Additional Inputs
With Python, AttributeScripts were limited to 1 input, so you couldn't add more inputs to a node. OpScript removes this restriction: OpScript nodes have a Display as multi input option that can be enabled. The OpScript is run on each location matches by its CEL expression, as evaluated in the left-most input (usually named "i0"). If you want to read an attribute from an additional input, you can specify the scenegraph location and input index:
-- Read from second input (for example, "i1"). local tacoAttrFromSecondInput = Interface.GetAttr('taco', '/root/whatever', 1)
SetAttr
Python:
SetAttr("type", ["subdmesh"])
Lua:
Interface.SetAttr("type", StringAttribute("subdmesh"))
Unlike AttributeScript, there is no implicit conversion from primitive types like strings and numbers (or lists thereof) to their corresponding Attribute types. OpScript requires that you construct an Attribute instance explicitly.
Listed below are the constructors for the various Attribute sub-classes:
- StringAttribute(string)
- FloatAttribute(number)
- DoubleAttribute(number)
- IntAttribute(number)
- GroupAttribute()
- NullAttribute()
Note: To delete an attribute in Lua, use the DeleteAttr() function provided by the Interface module.
Deleting an Attribute
To delete an attribute in Lua, use the DeleteAttr() functions provided by the Interface module.
Python:
SetAttr("taco") # setting it to "nothing" deletes it in python
Lua:
Interface.DeleteAttr("taco")
GetName, GetFullName
Python:
name = GetName() fullname = GetFullName()
Lua:
local name = Interface.GetOutputName() local fullname = Interface.GetOutputLocationPath()
XForm Manipulation
local xformGroup = Interface.GetGlobalXFormGroup() local xformMatrix = XFormUtils.CalcTransformMatrixAtTime(xformGroup, 0.0)
Util.AssetResolve
Python:
resolvedAsset = Util.AssetResolve("foo://bar")
Lua:
local assetPlugin = Asset.GetDefaultAssetPlugin() local resolvedAsset = assetPlugin:resolveAsset("foo://bar")
User Parameters
Python:
tacoList = user.taco tacoSingleValue = tacoList[0]
Lua:
local tacoParam = Interface.GetOpArg("user.taco") if tacoParam then local tacoList = tacoParam:getNearestSample(0.0) local tacoSingleValue = tacoParam:getValue() end
Language Basics
print()
Python:
print "tacoSingleValue", tacoSingleValue print "tacoList", tacoList
Lua:
print("tacoSingleValue", tacoSingleValue) -- if you have an 'array-like' table with consecutive indices for i, value in ipairs(tacoList) do print("tacoList[" .. i .. "]", value) end -- if you have a 'dictionary-like' table. Note that the order of iteration is undefined, much like Python for key, value in pairs (tacoDict) do print("tacoDict[" .. key .. "]", value) end
dir()
The dir() function in Python lets you introspect an object (or the current local scope), which can be useful for seeing what tools you have at your disposal. Lua doesn't have a precise equivalent, but any table can be iterated over using the pairs() function, so you can explore a lot in a similar way.
Python:
dir() dir(some_object)
Lua:
local keys={} for key, value in pairs(Interface) do table.insert(keys,key) end table.sort(keys) for index, value in ipairs(keys) do print(value) end
Comments
Python:
# This is a single line comment
Lua:
-- This is a single-line comment --[[This is a multi-line comment]]
String Concatenation
Python:
tacoConcat = "taco1" + "taco2"
Lua:
local tacoConcat = "taco1" .. "taco2"
String Manipulation
Most of the string operations you would do in Python are available in OpScript as part of the pystring module. For instance to split a string and get the last token, follow the example below.
Python:
path = "/foo/bar/baz" lastToken = path.split('/')[-1]
Lua, using pystring:
local path = "/foo/bar/baz" local pathTokens = pystring.split(path, "/") local lastToken = pathTokens[#pathTokens]
Lua, the "native" way:
local path = "/foo/bar/baz" local lastToken = nil -- string.gmatch returns an iterator of matches for token in string.gmatch(path, "[^/]+") do lastToken = token end
Slicing
Lua, the "native" way to slice a table requires a function:
local function slice(values, i1, i2) local n = #values -- default values for range i1 = i1 or 1 i2 = i2 or n if i2 < 0 then i2 = n + i2 + 1 elseif i2 > n then i2 = n end if i1 < 1 or i1 > n then return {} end local result = {} for i = i1,i2 do table.insert(result, values[i]) end return result end local path = "/foo/bar/baz" local pathTokens = pystring.split(path, "/") pathTokens = slice(pathTokens, 1, -2) local path = pystring.join("/", pathTokens)
math library
The math library is already loaded, by default. You can just use its functions, which are mostly the same as in Python. Examples include:
- math.sqrt()
- math.abs()
- math.sin()
Note: The official documentation of the math library can be found at http://www.lua.org/manual/5.1/manual.html#5.6.
Example usage of the math library can be found at http://lua-users.org/wiki/MathLibraryTutorial.
Arithmetic
For arithmetic, you use mostly the same operators as in Python (+, -, *, /, %).
An exception is power:
Python:
x**y
Lua:
x^y
You can alternately use the math library:
math.pow(x,y)
Executing External Scripts
Like execfile in AttributeScript, dofile in OpScript caches the compiled code for each file executed so that cooking thousands of locations on the render farm does not bring down the network.
Python:
execfile("/my/external/attribute_script.py")
Lua:
dofile("/my/external/op_script.lua")
Caveats
Be aware that module functions that directly map to existing C++ APIs use zero-based indices, even though Lua indices generally start at 1. This is done to make code as portable as possible between Lua and C++. For functions that return native Lua tables or list tables (such as IntAttribute:getNearestSample(0.0)), the return values are indexed in the Lua standard way, starting at 1.
Lua:
-- getChildName index argument is zero-based for i=0, groupAttr:getNumberOfChildren() - 1 do print(i .. ': ' .. groupAttr:getChildName(i)) end -- getNereastSample returns a table that uses one-based indices, as is typical -- in Lua. local attr = IntAttribute({1, 2, 3}) local values = attr:getNearestSample(0.0) -- Prints "1: 1", "2: 2", "3: 3" for index, value in ipairs(values) do print(index .. ': ' .. value) end
Sorry you didn't find this helpful
Why wasn't this helpful? (check all that apply)
Thanks for your feedback.
If you can't find what you're looking for or you have a workflow question, please try Foundry Support.
If you have any thoughts on how we can improve our learning content, please email the Documentation team using the button below.
Thanks for taking time to give us feedback.