Skip to content

Instantly share code, notes, and snippets.

@jedypod
Created February 21, 2020 17:00
Show Gist options
  • Save jedypod/f175eb6c2db328949ed5db976522c865 to your computer and use it in GitHub Desktop.
Save jedypod/f175eb6c2db328949ed5db976522c865 to your computer and use it in GitHub Desktop.
Nuke Python script to retime selected Roto, RotoPaint. or SplineWarp nodes.

Retime Roto

This is a python script for Nuke to retime roto shapes. It supports shapes only, not strokes, not opensplines.

It works by looping through each roto node, each shape in the roto node, and each point on the shape. It creates an expression on each point referencing a frame_lookup knob. Put a retime curve on this knob and your shapes will be retimed.

set cut_paste_input [stack 0]
version 12.1 v1
CheckerBoard2 {
inputs 0
centerlinewidth 0
name CheckerBoard2
selected true
xpos -480
ypos 14
postage_stamp false
}
Roto {
cliptype none
curves {{{v x3f99999a}
{f 0}
{n
{layer Root
{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}
{layer test
{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 x40e00000 x41300000 x41400000 x41900000 x41f00000 x42040000}
{{{xc12281a0 0 1 xc153371a 1}
{xc27bd782 -}
{x 4
{x426896a4 -}}
{x42708f60 x3f7f1780 1 0 1}}
{{xc2788b15 0 1 x413384f9 1}
{0 x410a0c38 1 x410a0c38 1}
{x 3
{x41c126f0 -}}
{x41c12700 -}
{x41951118 xc03057a0 1 0 1}}}
{{{x424c1bb8 0 1 x41e25c25 1}
{x432e0000 x409caff8 1 x409caff8 1}
{x43348755 x409caff8 1 x409caff8 1}
{x439f43ab x4245248f 1 x4245248f 1}
{x440361d4 x41eaaaaa 1 x41eaaaaa 1}
{x4453a1d5 x41cbaaaf 1 x382aaaab 1 258}
{x4453a1d7 x382aaaab 1 0 1}}
{{x42b96678 0 1 xc1a56678 1}
{x41200000 -}
{x 2
{x43592252 -}}
{x4480044a -}
{x43562251 xc2ca8000 1 0 1 258}
{x43562251 -}}}
{{{x412281a0 0 1 x41533718 1}
{x427bd780 -}
{x 4
{xc26896a0 -}}
{xc26a1d50 xbe435800 1 0 1}}
{{x42788b18 0 1 xc13384fc 1}
{0 xc10a0c38 1 xc10a0c38 1}
{x 4
{xc1c126e8 -}}
{xc1911288 x40405180 1 0 1}}}
{{{x42788b18 0 1 xc13384fb 1}
{0 xc10a0c3a 1 xc10a0c3a 1}
{x 5
{xc1c126f0 -}}}
{{xc12281a0 0 1 xc153371a 1}
{xc27bd782 -}
{x 5
{x426896a4 -}}}}
{{{xc22c5bba 0 1 x42a58b77 1}
{x43900000 -}
{x42edebd4 -}
{x43807af6 x42452491 1 x42452491 1}
{x43e7faf4 x41eaaaab 1 x41eaaaab 1}
{x44443d7b x41cbaaae 1 x382aaaab 1 258}
{x44443d7d x382aaaab 1 0 1}}
{{x435f98e6 0 1 xc189023d 1}
{x42f80000 xc178be3d 1 xc178be3d 1}
{x42884400 -}
{x42884401 x37c00000 1 x37c00000 1}
{x445ac880 -}
{x42824401 xc2ca8000 1 0 1 258}
{x42824401 -}}}
{{{xc2788b18 0 1 x413384fb 1}
{0 x410a0c3a 1 x410a0c3a 1}
{x 5
{x41c126f0 -}}}
{{x412281a0 0 1 x41533718 1}
{x427bd780 -}
{x 5
{xc26896a0 -}}}}
{{{x412281a0 0 1 x41533718 1}
{x427bd780 -}
{x 5
{xc26896a0 -}}}
{{x42788b18 0 1 xc13384fb 1}
{0 xc10a0c3a 1 xc10a0c3a 1}
{x 5
{xc1c126f0 -}}}}
{{{xc32dfc98 0 1 x4281cc6a 1}
{x432e0000 x4230c788 1 x4230c788 1}
{x4385fb1e x423991ca 1 x423991ca 1}
{x43cafb1e x42452490 1 x42452490 1}
{x44193d8e x41eaaaab 1 x41eaaaab 1}
{x44697d8f x41cbaaae 1 x382aaaab 1 258}
{x44697d91 x382aaaab 1 0 1}}
{{x43017b0a 0 1 x41d909ec 1}
{x436e0000 -}
{x40d21280 -}
{x40d21288 x37400000 1 x37400000 1}
{x444b6425 -}
{x40642501 xc2ca8000 1 0 1 258}
{x40642501 -}}}
{{{xc12281a0 0 1 xc153371a 1}
{xc27bd782 -}
{x 5
{x426896a0 -}}}
{{xc2788b18 0 1 x413384fb 1}
{0 x410a0c3a 1 x410a0c3a 1}
{x 5
{x41c126f0 -}}}}
{{{xc2788b14 0 1 x413384f8 1}
{0 x410a0c38 1 x410a0c38 1}
{x 5
{x41c126f0 -}}}
{{x412281a0 0 1 x41533718 1}
{x427bd780 -}
{x 5
{xc26896a4 -}}}}
{{{xc29fbd78 0 1 x4167f5d4 1}
{x42700000 x4223c28e 1 x4223c28e 1}
{x43a4c3d4 x42a30310 1 x42a30310 1}
{x43e9c3d4 x42452490 1 x42452490 1}
{x4428a1e9 x41eaaaa9 1 x41eaaaa9 1}
{x4478e1e9 x41cbaaac 1 x382aaaab 1 258}
{x4478e1eb x382aaaab 1 0 1}}
{{xbfb54fc0 0 1 x41bc0a3c 1}
{x42f80000 x417b2c0a 1 x417b2c0a 1}
{x 2
{x431b90e7 -}}
{x4470a43a -}
{x431890e9 xc2ca8000 1 0 1 258}
{x431890e9 -}}}
{{{x42788b18 0 1 xc13384fb 1}
{0 xc10a0c3a 1 xc10a0c3a 1}
{x 5
{xc1c126f0 -}}}
{{xc12281a0 0 1 xc153371a 1}
{xc27bd782 -}
{x 5
{x426896a4 -}}}}}} idem}
{tx x40e00000 x432e0000 x42f80000}
{a osw x41200000 osf 0 str 1 spx x44800000 spy x44428000 sb 1 ltn x40e00000 ltm x40e00000 tt x40e00000 b 0 g 0 fx
{{x4054e11c xc1c00000 0 1 x4117ddfe 1}
{x41b760e6 x42c80000 -}
{x42bd1b81 xc1e00000 -}
{x42fa6666 x42c00000 x40c23751 1 0 1}} fy
{{x4054e11c xc1c00000 0 1 x4117ddfe 1}
{x41b760e6 x42c80000 -}
{x42bd1b81 xc1e00000 -}
{x42fa6666 x42c00000 x40c23751 1 0 1}}}}
{curvegroup OpenSpline1 1049088 bezier
{{cc
{f 1056800}
{px
{0 x40800000 x41200000 x41500000 x41a00000 x41d80000 x42040000}
{{{f 36864}
{{0 -}}}
{{f 36864}
{{x40800000 -}}}}
{{a osw
{{f 36864}
{{0 1 0 1 0 1 272}
{x40800000 x40b48784 -}
{x41200000 1 -}
{x41500000 x40180001 -}
{x41a00000}
{x41d80000}
{x42040000}}} osf
{{f 36864}
{{0 0 -}
{x40800000}
{x41200000}
{x41500000 x42480010 -}
{x41a00000}
{x41d80000}
{x42040000}}}}
{{f 36864}
{{x43ce8004 0 1 xc296c006 1}
{x 2
{x43540000 -}}
{x 4
{x434dfffc -}}}}
{{f 36864}
{{x448a0000 0 1 xc2580000 1}
{x 2
{x44700000 -}}
{x 4
{x44777fff -}}}}}
{{{f 36864}
{{0 -}}}
{{f 36864}
{{xc0800000 -}}}}
{{{x 3
{xc3b50000 -}}
{x42700000 -}
{x 3
{xc2900000 -}}}
{{x 3
{x43360000 -}}
{x433b0000 -}
{x 3
{xc29a0000 -}}}}
{{a osw
{{0 1 -}
{x40800000}
{x41200000}
{x41500000}
{x41a00000 x40aede53 -}
{x41d80000}
{x42040000}} osf
{{0 x42aa3973 0 1 xc1ff562c 1}
{x40800000 0 -}
{x41200000}
{x41500000 x41c2e5a2 -}
{x41a00000}
{x41d80000 x42af7a73 -}
{x42040000}}}
{{x44130000 0 1 x42900000 1}
{x 2
{x44430000 -}}
{x 4
{x44250000 -}}}
{{x43ac0000 0 1 xc2190000 1}
{x 2
{x43720000 -}}
{x 4
{x43e08000 -}}}}
{{{x 3
{x43b50000 -}}
{xc2309b70 -}
{x 3
{x42c56850 -}}}
{{x 3
{xc3360000 -}}
{xc3099b58 x41e60bf0 1 x41e60bf0 1}
{x 3
{x42d31dd8 -}}}}
{{{x43560000 0 1 xc2f48000 1}
{xc2e00000 -}
{x 5
{xc287dff0 -}}}
{{xc1e7fff0 0 1 xc28ac002 1}
{xc3560000 -}
{x 5
{x4367c91c -}}}}
{{a osw
{{0 1 -}
{x40800000}
{x41200000}
{x41500000}
{x41a00000}
{x41d80000}
{x42040000}} osf
{{0 0 -}
{x40800000}
{x41200000}
{x41500000}
{x41a00000}
{x41d80000}
{x42040000 x4247bc01 x4147bc01 1 0 1}}}
{{x44a9c000 0 1 x41b40000 1}
{x 5
{x44b14000 -}}
{x44ac6000 xc11c0000 1 0 1}}
{{x43cd7fff 0 1 xc0fbffe8 1}
{x 5
{x43c30000 -}}
{x43db0000 x41400000 1 0 1}}}
{{{xc28c0000 0 1 x42888000 1}
{x42e00000 -}
{x 5
{x42080000 -}}}
{{x42ce0004 0 1 x42267ffd 1}
{x43560000 -}
{x 5
{xc2e80000 -}}}}
{{{0 -}}
{{0 -}}}
{{a osw
{{0 1 -}
{x40800000}
{x41200000 x40a35023 -}
{x41500000}
{x41a00000}
{x41d80000}
{x42040000}} osf
{{0 0 -}
{x40800000}
{x41200000 x424bce36 -}
{x41500000}
{x41a00000}
{x41d80000}
{x42040000}}}
{{x 2
{x44d8c000 -}}
{x 5
{x44dec000 -}}}
{{x 2
{x443b8000 -}}
{x 5
{x4440c001 -}}}}
{{{0 -}}
{{0 -}}}}} idem}
{tx x40800000 x44818000 x44126000}
{a osbe 0 osee 0 osw x41200000 osf 0 str 1 ltn x40800000 ltm x40800000 tt x41200000 b x3e28f5c3 g x3f347ae1 r x3f051eb8 opc
{{1 x3cfdf3b6 0 1 x3e3a0c4a 1}
{x41100000 1 -}
{x41600000 x3e7ae148 -}
{x41c00000 1 x3de7ef9e 1 0 1}}}}}
{curvegroup BSpline1 512 bspline
{{cc
{f 8192}
{px
{1 x40a00000 x41200000 x41880000 x41a00000}
{{a t
{{1 x3f6b851f -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x449c6001 0 1 xc22afff4 1}
{x448e2002 -}
{x 3
{x449c0002 -}}}
{{x44647fff 0 1 x41d80000 1}
{x44767fff -}
{x 3
{x445ffffe -}}}}
{{a t
{{1 x3f841893 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x44868000 -}}
{{x44460000 -}}}
{{a t
{{1 x3f818937 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x44a14000 -}}
{{x443b0000 -}}}
{{a t
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x44a8c000 -}}
{{x44578000 -}}}
{{a t
{{1 x3f828f5c -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x44aa8000 -}}
{{x44730000 -}}}
{{a t
{{1 x3f820c4a -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 2
{x44b04000 -}}
{x44c05fff -}
{x 2
{x44b5e000 -}}}
{{x 2
{x448b8000 -}}
{x447e3ffe -}
{x 2
{x4486a000 -}}}}
{{a t
{{1 x3f83126f -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 2
{x44ae4000 -}}
{x44c4bfff -}
{x44a1dfff -}
{x44b98000 x42bd0008 1 0 1}}
{{x 2
{x449c8000 -}}
{x44938000 -}
{x449affff -}
{x4496e000 xc183ffe0 1 0 1}}}
{{a t
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x44a44000 -}}
{{x447c0000 -}}}}}
{cc
{f 8192}
{px
{1 x40a00000 x41200000 x41880000 x41a00000}
{{a t
{{1 x3f6b851f -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 2
{xc2a7fff0 -}}
{xc1700000 -}
{xc2a7fff0 -}
{0 x4227fff0 1 0 1}}
{{x427c0000 0 1 x37c00000 1}
{x427c0010 -}
{xc0400100 -}
{x427c0000 -}
{0 xc1fc0000 1 0 1}}}
{{a t
{{1 x3f841893 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 4
{xc283fff8 -}}
{0 x4203fff8 1 0 1}}
{{x 4
{xc2900000 -}}
{0 x42100000 1 0 1}}}
{{a t
{{1 x3f818937 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 4
{x4257ffe0 -}}
{0 xc1d7ffe0 1 0 1}}
{{x 4
{xc24c0000 -}}
{0 x41cc0000 1 0 1}}}
{{a t
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 4
{x42640020 -}}
{0 xc1e40020 1 0 1}}
{{0 -}}}
{{a t
{{1 x3f828f5c -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 4
{x42400000 -}}
{0 xc1c00000 1 0 1}}
{{x 4
{x41700000 -}}
{0 xc0f00000 1 0 1}}}
{{a t
{{1 x3f820c4a -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{0 -}}
{{0 -}}}
{{a t
{{1 x3f83126f -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 4
{x41100080 -}}
{0 xc0900080 1 0 1}}
{{x 4
{x42c60000 -}}
{0 xc2460000 1 0 1}}}
{{a t
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} rp
{{1 1 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}} te
{{1 x40800000 -}
{x40a00000}
{x41200000}
{x41880000}
{x41a00000}}}
{{x 2
{xc28a0000 -}}
{x41100000 -}
{xc28a0000 -}
{0 x420a0000 1 0 1}}
{{x 2
{x42580020 -}}
{xc18fffc0 -}
{x42580020 -}
{0 xc1d80020 1 0 1}}}}}}
{tx 1 x44a39800 x44701000}
{a g x3e87ae14 opc
{{x41a00000 1 0 1 xbd0d3dcb 1}
{x42440000 0 xbd0d3dcb 1 0 1}} osw x41200000 osf 0 str 1 spx x44800000 spy x44428000 sb 1 tt x40c00000}}
{curvegroup Bezier1 512 bezier
{{cc
{f 8192}
{px
{1 x41200000 x41400000 x41700000 x41880000 x41c80000}
{{{0 -}}
{{0 -}}}
{{{x4418c000 0 1 xc1d80000 1}
{x 4
{x43e08000 -}}
{x44137ffe x41d37ff4 1 0 1}}
{{x 5
{x44a98001 -}}
{x44a98000 xb7c00000 1 0 1}}}
{{{0 -}}
{{0 -}}}
{{{x40800000 -}}
{{x42280000 -}}}
{{{x441a8000 0 1 xc1d80000 1}
{x 4
{x43e40000 -}}
{x44153ffe x41d37ff4 1 0 1}}
{{x 5
{x44984000 -}}
{x44983fff xb7c00000 1 0 1}}}
{{{xc0800000 -}}
{{xc2280000 -}}}
{{{xc0c00000 -}}
{{x41b00000 -}}}
{{{x441b0000 0 1 xc1d80000 1}
{x 4
{x43e50000 -}}
{x4415bffe x41d37ff4 1 0 1}}
{{x 5
{x44864000 -}}
{x44863fff xb7c00000 1 0 1}}}
{{{x40c00000 -}}
{{xc1b00000 -}}}
{{{xc2700000 -}}
{{x41800000 -}}}
{{{x442a0000 0 1 xc1900000 1}
{x44018000 xc1900000 1 0 1 258}
{x 3
{x44018000 -}}
{x4424bffe x41d37ff4 1 0 1}}
{{x 5
{x446e0000 -}}
{x446dffff xb7400000 1 0 1}}}
{{{x42700000 -}}
{{xc1800000 -}}}
{{{xc2700000 -}}
{{xc2200000 -}}}
{{{x445c8000 0 1 xc1d80000 1}
{x 4
{x44340000 -}}
{x44573ffe x41d37ff4 1 0 1}}
{{x 5
{x44748000 -}}
{x44747fff xb7400000 1 0 1}}}
{{{x42700000 -}}
{{x42200000 -}}}
{{{x40800000 -}}
{{xc1c00000 -}}}
{{{x44658000 0 1 xc1d80000 1}
{x 4
{x443d0000 -}}
{x44603ffe x41d37ff4 1 0 1}}
{{x 5
{x448e8000 -}}
{x448e7fff xb7c00000 1 0 1}}}
{{{xc0800000 -}}
{{x41c00000 -}}}
{{{xc1e00000 -}}
{{xc1f00000 -}}}
{{{x44820000 0 1 xc1911746 1}
{x445b8000 xc18dd174 1 xc18dd174 1}
{x44534000 -}
{x44563fff -}
{x44558000 -}
{x4478bffe x41d37ff4 1 0 1}}
{{x 2
{x44888000 -}}
{x44876000 -}
{x4489ffff -}
{x4487c000 xb8400000 1 xb8400000 1}
{x4487bfff -}}}
{{{x41e00000 -}}
{{x41f00000 -}}}
{{{x42100000 -}}
{{xc1e00000 -}}}
{{{x44820000 0 1 xc1911746 1}
{x445b8000 xc18dd174 1 xc18dd174 1}
{x44534000 -}
{x44563fff -}
{x44558000 -}
{x4478bffe x41d37ff4 1 0 1}}
{{x 2
{x44954000 -}}
{x44942000 -}
{x4496bfff -}
{x44948000 xb8400000 1 xb8400000 1}
{x44947fff -}}}
{{{xc2100000 -}}
{{x41e00000 -}}}
{{{x41600000 -}}
{{xc1000000 -}}}
{{{x44678000 0 1 xc1d80000 1}
{x 4
{x443f0000 -}}
{x44623ffe x41d37ff4 1 0 1}}
{{x 5
{x449c0000 -}}
{x449bffff xb7c00000 1 0 1}}}
{{{xc1600000 -}}
{{x41000000 -}}}
{{{xc0c00000 -}}
{{xc1c00000 -}}}
{{{x445b8000 0 1 xc1d80000 1}
{x 4
{x44330000 -}}
{x44563ffe x41d37ff4 1 0 1}}
{{x 5
{x44a38000 -}}
{x44a37fff xb7c00000 1 0 1}}}
{{{x40c00000 -}}
{{x41c00000 -}}}
{{{0 -}}
{{xc1e00000 -}}}
{{{x445b8000 0 1 xc1d80000 1}
{x 4
{x44330000 -}}
{x44563ffe x41d37ff4 1 0 1}}
{{x 5
{x44aec000 -}}
{x44aebfff xb7c00000 1 0 1}}}
{{{0 -}}
{{x41e00000 -}}}
{{{x42500000 -}}
{{xc1800000 -}}}
{{{x444c0000 0 1 xc1d80000 1}
{x 4
{x44238000 -}}
{x4446bffe x41d37ff4 1 0 1}}
{{x 5
{x44b70000 -}}
{x44b6ffff xb7c00000 1 0 1}}}
{{{xc2500000 -}}
{{x41800000 -}}}
{{{x41200000 -}}
{{x41000000 -}}}
{{{x442b0000 0 1 xc1d80000 1}
{x 4
{x44028000 -}}
{x4425bffe x41d37ff4 1 0 1}}
{{x 5
{x44b38000 -}}
{x44b37fff xb7c00000 1 0 1}}}
{{{xc1200000 -}}
{{xc1000000 -}}}}} idem}
{tx 1 x444d3b14 x4498a762}
{a osw x41200000 osf 0 str 1 spx x44800000 spy x44428000 sb 1 tt x40800000 b x3ef4c4f0 g x3f3539c9}}}}}}
toolbox {selectAll {
{ selectAll str 1 ssx 1 ssy 1 sf 1 }
{ createBezier str 1 ssx 1 ssy 1 sf 1 sb 1 tt 4 }
{ createBezierCusped str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ createBSpline str 1 ssx 1 ssy 1 sf 1 sb 1 tt 6 }
{ 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 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ eraser src 2 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ clone src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ reveal src 3 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ dodge src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ burn 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 src 1 str 1 ssx 1 ssy 1 sf 1 sb 1 }
{ smear 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}
color {0.5199999809 0.7049999833 0.1650000066 1}
color_panelDropped true
colorOverlay {0 0 0 0}
opacity {{curve x1 0.03099999949 x9 1 x14 0.2450000048 x24 1}}
lifetime_type "all frames"
lifetime_start 4
lifetime_end 4
motionblur_shutter_offset_type centred
name Roto2
selected true
xpos -480
ypos 62
}
TimeWarp {
lookup {{curve C x1 1 s2 x23 100 s2.099999905}}
time ""
filter none
name TimeWarp1
selected true
xpos -480
ypos 108
}
from __future__ import print_function
import nuke
import nuke.rotopaint as rp
import _curvelib as cl
def unselect():
_ = [n.setSelected(False) for n in nuke.allNodes(recurseGroups=True)]
def duplicate(node):
unselect()
node.setSelected(True)
nuke.nodeCopy('%clipboard')
unselect()
new_node = nuke.nodePaste('%clipboard')
new_node.setXYpos(node.xpos() + 120, node.ypos())
new_node.setInput(0, node.input(0))
return new_node
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(node):
# Get all shape stroke and layer elements from specified Roto, RotoPaint, or SplineWarp node
supported_classes = ['Roto', 'RotoPaint', 'SplineWarp3']
if node.Class() in supported_classes:
elements = {'Shapes': [], 'Strokes': []}
root_layer = node['curves'].rootLayer
elements = parse_layer(root_layer, elements, [root_layer])
return elements
def start(nodes=nuke.selectedNodes()):
# Retime all shapes in specified roto rotopaint and splinewarp nodes.
# OpenSplines and Strokes are not supported.
# For documentation check print help(_curvelib)
for node in nodes:
# Create copy of node to retime
node = duplicate(node)
elements = get_elements(node)
shapes = [e[0] for e in elements['Shapes']]
# strokes = [e[0] for e in elements['Strokes']]
# Add frame_lookup knob. This is where the user puts their retime curve.
if 'frame_lookup' not in node.knobs():
node.addKnob(nuke.Tab_Knob('Retime', 'Retime'))
node.addKnob(nuke.Double_Knob('frame_lookup', 'frame_lookup'))
for shape in shapes:
print('Retiming {0}'.format(shape.name))
# Set retime expression on each point in the shape for
# center, left and right tangents, for main curve and feather curve
for point in shape:
# Get AnimCurve objects for the point
# Note: OpenSpline objects are not supported.
# Seems like the width property of the spline is not supported in the Nuke Python API
point_data = [point.center, point.featherCenter, point.featherLeftTangent, point.featherRightTangent, point.leftTangent, point.rightTangent]
animcurves = [(d.getPositionAnimCurve(0), d.getPositionAnimCurve(1)) for d in point_data]
# Set retime expression on each animcurve
for animcurve_tuple in animcurves:
for animcurve in animcurve_tuple:
animcurve.useExpression = True
animcurve.expressionString = 'curve(frame_lookup)'
# Find all animated attributes of the shape and add retime expression to those as well.
attr_names = ['a', 'ao', 'bm', 'b', 'bo', 'bs', 'bsp', 'bt', 'bu', 'dh', 'ds', 'dt', 'ep1', 'ep2', 'ep3', 'ff', 'fo', 'ft', 'fx', 'fy', 'g', 'go', 'h', 'inv', 'ltm', 'ltn', 'ltt', 'mb', 'mbo', 'mbs', 'mbso', 'mbsot', 'nv', 'opc', 'pt', 'r', 'ro', 'src', 'spx', 'spy', 'sr', 'ssx', 'ssy', 'sso', 'sskx', 'ssky', 'sto', 'stot', 'str', 'stx', 'sty', 't', 'view', 'vis', 'we', 'ws']
shape_attrs = shape.getAttributes()
for attr_name in attr_names:
# Check if there are keyframes on this attr. If so we add an expression to retime
if shape_attrs.getNumberOfKeys(attr_name) > 0:
animcurve = shape_attrs.getCurve(attr_name)
animcurve.useExpression = True
animcurve.expressionString = 'curve(frame_lookup)'
node['curves'].changed()
if __name__=='__main__':
start()
@LewieFX
Copy link

LewieFX commented Jul 7, 2021

Hey Jed,
I am a bit confused how to use this. I run the script selecting my roto nodes and it works but with no expression in the frame lookup tab. I am not sure how i am meant to use this script. Could you please help?

@jedypod
Copy link
Author

jedypod commented Jul 7, 2021

Hey @LewieFX,
It's been a while since I looked at this. If I recall correctly, and by looking at the code I believe the intended use is to run this script on a roto node. It will loop through all the shapes and add an expression so that the timing of the animation is controlled by the frame lookup knob. The idea is to retime the roto shapes themselves instead of trying to retime the image that the roto node generates, which will usually result in artifacts. This is most applicable for shots with retimes.

So for this to work you would need to put whatever retime curve animation into the frame lookup knob. Does it make sense?

@LewieFX
Copy link

LewieFX commented Jul 7, 2021

So for this to work you would need to put whatever retime curve animation into the frame lookup knob. Does it make sense?

That does make sense but seems like its not working for my shot. It seems to have it some frames but then loses it on others. Would baked tracks in roto layers be effecting it?

@LewieFX
Copy link

LewieFX commented Jul 7, 2021

Would baked tracks in roto layers be effecting it?

After coming back, and testing this it seems like it doesn't like tracking data being in the roto layer. Looks like it results in some adding of values and therefore offsetting the shape.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment