Skip to content

Instantly share code, notes, and snippets.

@jedypod
Last active May 6, 2022 19:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jedypod/52cf750e02ee2cee2e407b16e1616540 to your computer and use it in GitHub Desktop.
Save jedypod/52cf750e02ee2cee2e407b16e1616540 to your computer and use it in GitHub Desktop.
some examples for setting expressions in the python api for the nuke rotopaint system
set cut_paste_input [stack 0]
push $cut_paste_input
RotoPaint {
cliptype none
curves {{{v x3f99999a}
{f 0}
{n
{layer Root
{f 2097152}
{t x44800000 x44428000}
{a pt1x 0 pt1y 0 pt2x 0 pt2y 0 pt3x 0 pt3y 0 pt4x 0 pt4y 0 ptex00 0 ptex01 0 ptex02 0 ptex03 0 ptex10 0 ptex11 0 ptex12 0 ptex13 0 ptex20 0 ptex21 0 ptex22 0 ptex23 0 ptex30 0 ptex31 0 ptex32 0 ptex33 0 ptof1x 0 ptof1y 0 ptof2x 0 ptof2y 0 ptof3x 0 ptof3y 0 ptof4x 0 ptof4y 0 pterr 0 ptrefset 0 ptmot x40800000 ptref 0}
{layer Layer1
{f 2097664}
{t x44800000 x44428000}
{a pt1x 0 pt1y 0 pt2x 0 pt2y 0 pt3x 0 pt3y 0 pt4x 0 pt4y 0 ptex00 0 ptex01 0 ptex02 0 ptex03 0 ptex10 0 ptex11 0 ptex12 0 ptex13 0 ptex20 0 ptex21 0 ptex22 0 ptex23 0 ptex30 0 ptex31 0 ptex32 0 ptex33 0 ptof1x 0 ptof1y 0 ptof2x 0 ptof2y 0 ptof3x 0 ptof3y 0 ptof4x 0 ptof4y 0 pterr 0 ptrefset 0 ptmot x40800000 ptref 0}
{curvegroup Ellipse1 512 bezier
{{cc
{f 8192}
{px 1
{xc2576420 0}
{x445de000 x44660000}
{x42576420 0}
{0 xc2626fd0}
{x44764000 x447fa000}
{0 x42626fc0}
{x42576420 0}
{x445de000 x448ca000}
{xc2576420 0}
{0 x42626fc0}
{x44458000 x447fa000}
{0 xc2626fd0}}}
{cc
{f 8192}
{p
{{{1 xc2576420}}
{{1 0}}}
{{{1 0}}
{{1 0}}}
{{{1 x42576420}}
{{1 0}}}
{{{1 0}}
{{1 xc2626fd0}}}
{{{1 0}}
{{1 0}}}
{{{1 0}}
{{1 x42626fc0}}}
{{{1 x42576420}}
{{1 0}}}
{{{1 0}}
{{1 0}}}
{{{1 xc2576420}}
{{1 0}}}
{{{1 0}}
{{1 x42626fc0}}}
{{{1 0}}
{{1 0}}}
{{{1 0}}
{{1 xc2626fd0}}}}}}
{tx 1 x445de000 x447fa000}
{a osw x41200000 osf 0 str 1 spx x44800000 spy x44428000 sb 1 tt x40e00000}}
{layer Layer2
{f 2097664}
{t x44800000 x44428000}
{a pt1x 0 pt1y 0 pt2x 0 pt2y 0 pt3x 0 pt3y 0 pt4x 0 pt4y 0 ptex00 0 ptex01 0 ptex02 0 ptex03 0 ptex10 0 ptex11 0 ptex12 0 ptex13 0 ptex20 0 ptex21 0 ptex22 0 ptex23 0 ptex30 0 ptex31 0 ptex32 0 ptex33 0 ptof1x 0 ptof1y 0 ptof2x 0 ptof2y 0 ptof3x 0 ptof3y 0 ptof4x 0 ptof4y 0 pterr 0 ptrefset 0 ptmot x40800000 ptref 0}
{curvegroup OpenSpline1 1049088 bezier
{{cc
{f 1056800}
{px 1
{xc0c00000 x41c00000}
{{a osw
{{1 1}} osf
{{1 0}}} x43220000 x44930000}
{x40c00000 xc1c00000}
{xc2880000 x41200000}
{{a osw
{{1 1}} osf
{{1 0}}} x43a50000 x44618000}
{x42880000 xc1200000}
{xc0800000 xc1200000}
{{a osw
{{1 1}} osf
{{1 0}}} x441e8000 x446b0000}
{x40800000 x41200000}
{0 0}
{{a osw
{{1 1}} osf
{{1 0}}} x439d0000 x44994000}
{0 0}}} idem}
{tx 1 x43b40000 x4484a000}
{a osbe 0 osee 0 osw x41200000 osf 0 str 1 tt x41200000}}
{cubiccurve Brush1 512 catmullrom
{cc
{f 2080}
{px 1
{x44bf4000 x4499c000 x3e352c00}
{x44be0000 x4499c000 x3eefba00}
{x44ba4000 x4499c000 x3f20a800}
{x44b22000 x44974000 x3f332c00}
{x44a96000 x44938000 x3f3a2e00}
{x44a96000 x448ac000 x3f3e6f00}
{x44b4a000 x4483e000 x3f40b000}
{x44c08000 x447b4000 x3f417000}
{x44bea000 x446d8000 x3f473100}
{x44afa000 x4455c000 x3f49f200}
{x44a3c000 x443cc000 x3c400000}
{x44a46000 x443b8000 0}}}
{tx 1 x44b352ab x4482d555}
{a ro 0 go 0 bo 0 ao 0 h 0 bu 1 str 1 spx x44800000 spy x44428000 sb 1 ltt x40000000 tt x41880000}}}}
{curvegroup Bezier1 512 bezier
{{cc
{f 8192}
{px 0
{0 xc0000000}
{x443c0000 x443c0000}
{0 x40000000}
{xc2480000 x42580000}
{x442f8000 x43dc0000}
{x42480000 xc2580000}
{xc1c00000 xc2280000}
{x446f8000 x43b00000}
{x41c00000 x42280000}
{x42080000 xc1900000}
{x44780000 x442d8000}
{xc2080000 x41900000}
{x41f00000 x40000000}
{x44538000 x444a8000}
{xc1f00000 xc0000000}}} idem}
{tx 0 x44548000 x44186666}
{a osw x41200000 osf 0 str 1 spx x44800000 spy x44428000 sb 1 ltn 0 ltm 0 tt x40800000}}}}}}
toolbox {selectAll {
{ selectAll str 1 ssx 1 ssy 1 sf 1 }
{ createBezier str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ createBezierCusped str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ createBSpline str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ createEllipse str 1 ssx 1 ssy 1 sf 1 sb 1 tt 7 }
{ createRectangle str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ createRectangleCusped str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ brush h 0 str 1 ssx 1 ssy 1 sf 1 sb 1 tt 17 }
{ eraser h 0 src 2 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ clone h 0 src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 tt 19 }
{ reveal h 0 src 3 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ dodge h 0 src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ burn h 0 src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ blur src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ sharpen h 0 src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ smear h 0 src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
} }
toolbar_brush_hardness 0.200000003
toolbar_source_transform_scale {1 1}
toolbar_source_transform_center {1024 778}
colorOverlay {0 0 0 0}
lifetime_type "all frames"
motionblur_shutter_offset_type centred
brush_spacing 0.05000000075
brush_hardness 0
source_black_outside true
name Roto
selected true
xpos -10628
ypos 1382
}
NoOp {
inputs 0
name Test
selected true
xpos -10631
ypos 1480
addUserKnob {20 Test}
addUserKnob {22 test l Test T "import sys\nsys.path.insert(0, nuke.root()\['project_directory'].evaluate())\nimport rotopaint_examples\nreload(rotopaint_examples)\nrotopaint_examples.start()" +STARTLINE}
}
from __future__ import print_function
import nuke
import nuke.rotopaint as rp
import _curvelib as cl
'''
# Nuke rotopaint API reference
https://learn.foundry.com/nuke/developers/120/pythonreference/
# nuke python devguide on rotopaint
https://learn.foundry.com/nuke/developers/120/pythondevguide/rotopaint.html
'''
def parse_layer(root_layer, elements, parents):
# recursively gather all shapes and strokes in specified roto layer
for element in root_layer:
if isinstance(element, rp.Shape):
print('adding shape element {0}'.format(element.name))
elements['Shapes'].append([element, parents])
elif isinstance(element, rp.Stroke):
print('adding Stroke element {0}'.format(element.name))
elements['Strokes'].append([element, parents])
elif isinstance(element, rp.Layer):
parent_names = [l.name for l in parents]
parent_names.reverse()
print('Getting contents of layer element {0}\nwith parent {1}'.format(
element.name, '/'.join(parent_names)))
parents_copy = parents[:]
parents_copy.insert(0, element)
elements = parse_layer(element, elements, parents_copy)
return elements
def get_elements(roto_node):
# Get all shape stroke and layer elements from specified Roto, RotoPaint, or SplineWarp node
elements = {
'Shapes': [],
'Strokes': [],
}
root_layer = roto_node['curves'].rootLayer
elements = parse_layer(root_layer, elements, [root_layer])
return elements
def set_expressions(roto_node, shapename):
# get a specific shape
shape = roto_node['curves'].toElement(shapename)
#print(help(shape))
# We will set an expression on the translate, rotate, and scale for this shape
xform = shape.getTransform()
# Find all the things you can do with this object with
print(help(xform))
# First we have to create an _curvelib.AnimCurve object to hold our animation curve.
translation_curve_x = cl.AnimCurve()
translation_curve_y = cl.AnimCurve()
rotation_curve = cl.AnimCurve()
scale_curve = cl.AnimCurve()
# To set an expression on our curve we have to set the expressionString and useExpression to True
translation_curve_x.expressionString = 'frame'
translation_curve_y.expressionString = 'frame%2'
rotation_curve.expressionString = 'frame'
scale_curve.expressionString = 'frame/100+0.5'
# set useExpression=True for all curves
for curve in [translation_curve_x, translation_curve_y, rotation_curve, scale_curve]:
curve.useExpression = True
# Now we overwrite the animcurves on the shape
xform.setTranslationAnimCurve(0, translation_curve_x)
xform.setTranslationAnimCurve(1, translation_curve_y)
# Index value of setRotationAnimCurve is 2 even though there is only 1 parameter...
# http://www.mail-archive.com/nuke-python@support.thefoundry.co.uk/msg02295.html
xform.setRotationAnimCurve(2, rotation_curve)
xform.setScaleAnimCurve(0, scale_curve)
xform.setScaleAnimCurve(1, scale_curve)
def start():
nuke.root().begin()
roto_node = nuke.toNode('Roto')
# # get contents of roto node
# elements = get_elements(roto_node)
# print(elements)
set_expressions(roto_node, 'Layer1/Ellipse1')
if __name__=='__main__':
start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment