<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://berniebernie.fr/mediawiki-1.37.1/index.php?action=history&amp;feed=atom&amp;title=Nuke_Python</id>
	<title>Nuke Python - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://berniebernie.fr/mediawiki-1.37.1/index.php?action=history&amp;feed=atom&amp;title=Nuke_Python"/>
	<link rel="alternate" type="text/html" href="https://berniebernie.fr/mediawiki-1.37.1/index.php?title=Nuke_Python&amp;action=history"/>
	<updated>2026-04-29T18:18:47Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>https://berniebernie.fr/mediawiki-1.37.1/index.php?title=Nuke_Python&amp;diff=690&amp;oldid=prev</id>
		<title>Bernie: /* Natron fill write path with parent node path shenanigans */</title>
		<link rel="alternate" type="text/html" href="https://berniebernie.fr/mediawiki-1.37.1/index.php?title=Nuke_Python&amp;diff=690&amp;oldid=prev"/>
		<updated>2023-06-06T10:02:49Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Natron fill write path with parent node path shenanigans&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en-GB&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 12:02, 6 June 2023&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;Line 1:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 1:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;=== Nuke find sequences on server and create a write node for each sequence ===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Not the most beautiful code but works for what I needed.&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;This one assumes there is a 0001.exr in each file sequence, creates a .png write. (yeah png bad, I know).&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;pre&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;import nuke, glob&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;shots = glob.glob(&#039;D:/2022/projectPath/someFolder/SQ*/SQ*_SH*/moreFolders/exr/*0001.exr&#039;, recursive=True)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;for shot in shots:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    frames = glob.glob(shot.replace(&#039;0001.exr&#039;,&#039;*.exr&#039;))&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    first = int(frames[0].split(&#039;.exr&#039;)[0][-4:])&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    last = int(frames[-1].split(&#039;.exr&#039;)[0][-4:])&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    shot = shot.replace(&quot;0001.exr&quot;,&quot;####.exr&quot;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    shot = shot.replace(&quot;\\&quot;,&quot;/&quot;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    read = nuke.nodes.Read (file=shot,first=first,last=last)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    expression = &quot;[python {nuke.thisNode().input(0).knob(&#039;file&#039;).value().replace(&#039;exr&#039;,&#039;png&#039;)}]&quot;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    write = nuke.nodes.Write(inputs=[read],channels=&#039;rgba&#039;,file=expression,file_type=&#039;png&#039;,create_directories=&#039;1&#039;,use_limit=&#039;1&#039;,first=&#039;this.input.first&#039;,last=&#039;this.input.last&#039;)&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    debug = shot.split(&#039;/&#039;)[-1]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;    print(&#039;{} {}-{}&#039;.format(debug,first,last))&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/pre&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Natron fill write path with parent node path shenanigans===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== Natron fill write path with parent node path shenanigans===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Bernie</name></author>
	</entry>
	<entry>
		<id>https://berniebernie.fr/mediawiki-1.37.1/index.php?title=Nuke_Python&amp;diff=663&amp;oldid=prev</id>
		<title>Bernie: /* Natron right click to create a PNG sequence from a folder */</title>
		<link rel="alternate" type="text/html" href="https://berniebernie.fr/mediawiki-1.37.1/index.php?title=Nuke_Python&amp;diff=663&amp;oldid=prev"/>
		<updated>2023-03-08T11:40:33Z</updated>

		<summary type="html">&lt;p&gt;&lt;span dir=&quot;auto&quot;&gt;&lt;span class=&quot;autocomment&quot;&gt;Natron right click to create a PNG sequence from a folder&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;=== Natron fill write path with parent node path shenanigans===&lt;br /&gt;
&lt;br /&gt;
This is kinda hackish, finds the the oldest grandparent/readfile and uses it to generate the path of the write node. No error checking but a maxloop of 20 because While==crash&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
node = thisNode&lt;br /&gt;
a = 0&lt;br /&gt;
while True:&lt;br /&gt;
	a = a + 1&lt;br /&gt;
	try:&lt;br /&gt;
		parent = node.getInput(0)&lt;br /&gt;
	except:&lt;br /&gt;
		pass&lt;br /&gt;
	if a &amp;gt;= 20 or not parent  or node.getPluginID() == &amp;#039;fr.inria.built-in.Read&amp;#039;:&lt;br /&gt;
		break&lt;br /&gt;
	else:&lt;br /&gt;
		node = parent&lt;br /&gt;
#return(str(node.getScriptName()))&lt;br /&gt;
infile = node.getParam(&amp;#039;filename&amp;#039;).get()&lt;br /&gt;
filename = infile.rsplit(&amp;#039;/&amp;#039;,1)&lt;br /&gt;
basename = filename[1].rsplit(&amp;#039;.&amp;#039;,1)[0]&lt;br /&gt;
a = filename[0]+&amp;#039;/&amp;#039;+basename +&amp;#039;_jpg/&amp;#039;+basename +&amp;#039;.####.jpg&amp;#039;&lt;br /&gt;
return(str(a))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Write node file using topmost read node file name ===&lt;br /&gt;
if input is &amp;lt;code&amp;gt;//path/to/myFile.mp4&amp;lt;/code&amp;gt;, output will be &amp;lt;code&amp;gt;//prodX/folderwhereshitisgonnabesaved/220919/myFile_9x16.mov&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Select write node(s) and run script&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
prefix = &amp;#039;//prodX/folderwhereshitisgonnabesaved/220919/&amp;#039;&lt;br /&gt;
suffix = &amp;#039;_9x16.mov&amp;#039;&lt;br /&gt;
&lt;br /&gt;
writes = nuke.selectedNodes()&lt;br /&gt;
for write in writes:&lt;br /&gt;
    n = write&lt;br /&gt;
    while n.inputs():&lt;br /&gt;
        n = n.input(0)    &lt;br /&gt;
    if n.Class() == &amp;#039;Read&amp;#039;:&lt;br /&gt;
        file = n.knob(&amp;#039;file&amp;#039;).value()&lt;br /&gt;
        filename = os.path.basename(file)&lt;br /&gt;
        filename = filename.split(&amp;#039;.&amp;#039;)[-2]&lt;br /&gt;
        write = write.knob(&amp;#039;file&amp;#039;).setValue( prefix + filename + suffix )&lt;br /&gt;
    else:&lt;br /&gt;
        print(&amp;#039;Topmost node found for &amp;#039;+write.name()+ &amp;#039; is not a read file but: &amp;#039;+n.Class()+&amp;#039; (&amp;#039;+n.name()+&amp;#039;)&amp;#039;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Natron right click to create a PNG sequence from a folder ===&lt;br /&gt;
==== version a ====&lt;br /&gt;
The idea is that I have a .ntp setup that works but I want to change the in and out, and I can&amp;#039;t manage to make the natron command line flags to work properly.&lt;br /&gt;
So given a &amp;#039;read&amp;#039; node called &amp;#039;&amp;#039;&amp;#039;inRead&amp;#039;&amp;#039;&amp;#039; and &amp;#039;write&amp;#039; node called &amp;#039;&amp;#039;&amp;#039;outWrite&amp;#039;&amp;#039;&amp;#039;, here&amp;#039;s what I do&lt;br /&gt;
&lt;br /&gt;
* Use a commandline in my shell:sendto: &amp;lt;code&amp;gt;&amp;quot;C:\Program Files\Natron\bin\NatronRenderer.exe&amp;quot; &amp;quot;C:\Users\Me\Documents\natron\ocio.ntp&amp;quot; -l &amp;quot;C:\Users\Me\Documents\natron\ocio.py&amp;quot; -i inRead %1 &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* In my &amp;lt;code&amp;gt;ocio.py&amp;lt;/code&amp;gt; have code to figure out a proper naming scheme:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import sys, pathlib&lt;br /&gt;
&lt;br /&gt;
file = sys.argv[-1]&lt;br /&gt;
file = file.replace(&amp;#039;\\&amp;#039;, &amp;#039;/&amp;#039;)&lt;br /&gt;
filename = file.rsplit(&amp;#039;/&amp;#039;,1)&lt;br /&gt;
basename = filename[1].rsplit(&amp;#039;.&amp;#039;,1)[0]&lt;br /&gt;
&lt;br /&gt;
a = filename[0]+&amp;#039;/&amp;#039;+basename +&amp;#039;_jpg/&amp;#039;+basename +&amp;#039;.####.jpg&amp;#039;&lt;br /&gt;
&lt;br /&gt;
app.inRead.filename.set(file)&lt;br /&gt;
app.outWrite.filename.set(a)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==== version b ====&lt;br /&gt;
To set in shell:sendto folder&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
@echo off&lt;br /&gt;
&amp;quot;C:\Program Files\INRIA\Natron-2.3.14\bin\Natron.exe&amp;quot; -l &amp;quot;C:\Users\Me\Documents\natron\to_file.py&amp;quot; %1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to_file.py:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
from NatronEngine import*&lt;br /&gt;
from NatronGui import *&lt;br /&gt;
import sys&lt;br /&gt;
import os&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
pathArg = str(sys.argv[-1])&lt;br /&gt;
pathArg = pathArg.replace(os.sep, &amp;#039;/&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
if os.path.isdir(pathArg):&lt;br /&gt;
	firstFile = os.listdir(pathArg)[0]&lt;br /&gt;
	pathArg = pathArg+&amp;#039;/&amp;#039;+firstFile&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def sequence(file):&lt;br /&gt;
	&amp;#039;&amp;#039;&amp;#039;given a file path, return a dictionnary with [directory, filename (without number and extension), start frame, end frame, padding, extension]&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
	# given  C:/path/the_sequence_0033.jpg&lt;br /&gt;
	# like so [&amp;#039;c:/path/&amp;#039;,&amp;#039;the_sequence_&amp;#039;,1,100,4,&amp;#039;.jpg&amp;#039;]&lt;br /&gt;
&lt;br /&gt;
	if os.path.isfile(file):&lt;br /&gt;
		reg = r&amp;#039;^(.+?)([0-9]+)\.([.a-zA-Z]{1,7})$&amp;#039;&lt;br /&gt;
		match = re.match(reg, file,re.IGNORECASE)&lt;br /&gt;
		if match:&lt;br /&gt;
			#return target&lt;br /&gt;
			newReg = r&amp;#039;(&amp;#039;+os.path.basename(match.groups()[0])+&amp;#039;)(\d*)\.(&amp;#039;+match.groups()[2]+&amp;#039;)&amp;#039;&lt;br /&gt;
						&lt;br /&gt;
			#bit convoluted but it will help me pick the first image of sequence that matches selection&lt;br /&gt;
			filelist = []&lt;br /&gt;
			target = os.path.dirname(file)&lt;br /&gt;
			for f in os.listdir(target):&lt;br /&gt;
				match = re.match(newReg, f,re.IGNORECASE)&lt;br /&gt;
				if match:&lt;br /&gt;
					filelist.append(match.groups())&lt;br /&gt;
			return [ target , filelist[0][0] , int(filelist[0][1]) , int(filelist[-1][1]) , len(filelist[0][1]) , filelist[0][2] ]&lt;br /&gt;
&lt;br /&gt;
filePath = sequence(pathArg)&lt;br /&gt;
inPath = filePath[0]+&amp;#039;/&amp;#039;+filePath[1]+(&amp;#039;#&amp;#039; * filePath[4])+&amp;#039;.&amp;#039;+filePath[5]&lt;br /&gt;
&lt;br /&gt;
app = natron.getGuiInstance(0)&lt;br /&gt;
&lt;br /&gt;
reader = app.createReader(inPath)&lt;br /&gt;
reader.setScriptName(&amp;quot;readin&amp;quot;)&lt;br /&gt;
writer = app.createWriter(&amp;quot;&amp;quot;)&lt;br /&gt;
writer.getParam(&amp;quot;formatType&amp;quot;).setValue(0)&lt;br /&gt;
writer.connectInput(0,reader)&lt;br /&gt;
&lt;br /&gt;
## i wanted to use an expression but apparently this breaks Natron&lt;br /&gt;
#expression = &amp;quot;import os;a = &amp;quot;+reader.getScriptName()+&amp;quot;.filename.get();path = os.path.dirname(a)+&amp;#039;_png/&amp;#039;+os.path.basename(a)+&amp;#039;.png&amp;#039;;return path;&amp;quot;&lt;br /&gt;
#writer.getParam(&amp;quot;filename&amp;quot;).setExpression(expression,1)&lt;br /&gt;
&lt;br /&gt;
outFile = filePath[0]+&amp;#039;_png/&amp;#039;+filePath[1]+(&amp;#039;#&amp;#039; * filePath[4])+&amp;#039;.&amp;#039;+filePath[5]+&amp;#039;.png&amp;#039;&lt;br /&gt;
writer.getParam(&amp;quot;filename&amp;quot;).setValue(outFile)&lt;br /&gt;
app.render(writer,app.timelineGetLeftBound(),app.timelineGetRightBound())&lt;br /&gt;
app.closeProject()&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Nuke Text Font TCL Python===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[python {nuke.thisNode().input(0).input(0).knob(&amp;#039;file&amp;#039;).value().split(&amp;#039;/&amp;#039;)[-1][:-9]}]&lt;br /&gt;
&lt;br /&gt;
get gandparent value of knob&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Natron Read File path to Text Overlay expression ===&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/R0Hvhkv.png&lt;br /&gt;
&lt;br /&gt;
I have a bunch of looping 10 frame sequences and I want to view the in a sequence with their file locations shown,I&amp;#039;ve used a switch node to switch which read node it is reading from every ten frames using &amp;#039;&amp;#039;(frame-1)/10&amp;#039;&amp;#039;.&lt;br /&gt;
Here&amp;#039;s what I added to the text node expression as shown in screenshot (it basically gets the file path of whichever input of the switch it finds):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#multiline is turned on, and you need the &amp;#039;ret&amp;#039; variable at the end&lt;br /&gt;
switchNode = thisNode.getInput(0)&lt;br /&gt;
currentReadNode = switchNode.getInput(switchNode.getParam(&amp;#039;which&amp;#039;).get())&lt;br /&gt;
ret = currentReadNode.getParam(&amp;#039;filename&amp;#039;).get().split(&amp;#039;/&amp;#039;)[-1]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create dots from selected ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
s = nuke.selectedNodes()&lt;br /&gt;
counter = -1&lt;br /&gt;
pos = [0,0]&lt;br /&gt;
dots = []&lt;br /&gt;
#dots are super &amp;#039;sticky&amp;#039; need to remove selection&lt;br /&gt;
for node in nuke.allNodes(recurseGroups=True):&lt;br /&gt;
    node[&amp;#039;selected&amp;#039;].setValue(False)&lt;br /&gt;
for n in reversed(s):&lt;br /&gt;
    counter += 1&lt;br /&gt;
    dot=nuke.createNode(&amp;#039;Dot&amp;#039;)&lt;br /&gt;
    dot.setInput(0, n)&lt;br /&gt;
    if counter == 0:&lt;br /&gt;
        #dot.autoplace()&lt;br /&gt;
        pos = [dot[&amp;#039;xpos&amp;#039;].value(),dot[&amp;#039;ypos&amp;#039;].value()]&lt;br /&gt;
        x = int(pos[0])&lt;br /&gt;
        y = int(pos[1])&lt;br /&gt;
        dot.setXYpos(x,y)&lt;br /&gt;
    else:&lt;br /&gt;
        x = int(pos[0]+counter*30)&lt;br /&gt;
        y = int(pos[1])&lt;br /&gt;
        dot.setXYpos(x,y)&lt;br /&gt;
&lt;br /&gt;
    dot.knob(&amp;#039;label&amp;#039;).setValue(n.name())&lt;br /&gt;
    dots.append(dot)&lt;br /&gt;
&lt;br /&gt;
for d in dots:&lt;br /&gt;
    d[&amp;#039;selected&amp;#039;].setValue(True)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== switch with inputs according to y pos ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def getKey(item):&lt;br /&gt;
    return item[&amp;#039;ypos&amp;#039;].value()&lt;br /&gt;
&lt;br /&gt;
sel = nuke.selectedNodes()&lt;br /&gt;
sorted(sel, key=getKey)&lt;br /&gt;
&lt;br /&gt;
switch = nuke.nodes.Switch(inputs=sel)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Check MXI SLs with Nuke (maxwell render) ===&lt;br /&gt;
Reads metadata&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/fAIuyTt.png&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def checkMXI_SL():&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;takes mxi read node and checks its SLs metadata and outputs frames under certain treshold&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    sl_threshold = 18.0&lt;br /&gt;
    txt = nuke.getInput(&amp;#039;Print frames with SL below:&amp;#039;, str(sl_threshold))&lt;br /&gt;
    if txt:&lt;br /&gt;
        sl_threshold = float(txt)&lt;br /&gt;
    output = &amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
    task = nuke.ProgressTask(&amp;quot;Checking MXI SLs&amp;quot;) &lt;br /&gt;
    task.setMessage(&amp;quot;Progress&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    for node in nuke.selectedNodes():&lt;br /&gt;
        if node.Class() == &amp;#039;Read&amp;#039;:&lt;br /&gt;
            firstframe = int(node[&amp;#039;first&amp;#039;].value())&lt;br /&gt;
            #lastframe = firstframe + 10&lt;br /&gt;
            lastframe = int(node[&amp;#039;last&amp;#039;].value())&lt;br /&gt;
            for i in range(firstframe, lastframe):&lt;br /&gt;
                percentage = int(100.0*(i-firstframe)/(lastframe-firstframe))&lt;br /&gt;
                task.setProgress(percentage)&lt;br /&gt;
                if task.isCancelled(): &lt;br /&gt;
                    break;&lt;br /&gt;
&lt;br /&gt;
                sl = node.metadata(&amp;#039;SAMPLING_LEVEL&amp;#039;,i)&lt;br /&gt;
                if  sl &amp;lt; sl_threshold:&lt;br /&gt;
                        task.setMessage(&amp;#039;Frame [&amp;#039;+str(i)+&amp;#039;] SL&amp;#039;+&amp;quot;{0:.1f}&amp;quot;.format(sl))                        &lt;br /&gt;
                        logline = &amp;#039;Frame &amp;#039; + str(i) + &amp;#039;: &amp;#039; + &amp;quot;{0:.2f}&amp;quot;.format(sl) + &amp;#039;\n&amp;#039;&lt;br /&gt;
                        output = output + logline&lt;br /&gt;
            task.setProgress(100)&lt;br /&gt;
    del task&lt;br /&gt;
&lt;br /&gt;
    p = nuke.Panel(&amp;#039;Results&amp;#039;)&lt;br /&gt;
    if output == &amp;#039;&amp;#039;:&lt;br /&gt;
        output = &amp;#039;All MXI are above or equal to &amp;#039;+str(sl_threshold)&lt;br /&gt;
    p.addNotepad(&amp;#039;Results:&amp;#039;,output)&lt;br /&gt;
    ret = p.show()&lt;br /&gt;
&lt;br /&gt;
checkMXI_SL()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rainbow colored gradient in nuke expression ===&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/dlg2rOF.png&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
red   : ( r * 6 &amp;gt;= 2 &amp;amp;&amp;amp; r * 6 &amp;lt;= 4 ) ? 0 : ( r * 6 &amp;lt;= 1 || r * 6  &amp;gt;= 5) ? 1 : ( 1 - abs ( ( r * 6 ) % 2 - 1 ) )&lt;br /&gt;
green : ( r * 6 &amp;gt;= 4 &amp;amp;&amp;amp; r * 6 &amp;lt;= 6 ) ? 0 : ( r * 6 &amp;gt;= 1 &amp;amp;&amp;amp; r * 6  &amp;lt;= 3) ? 1 : ( 1 - abs ( ( r * 6 ) % 2 - 1 ) )&lt;br /&gt;
blue  : ( r * 6 &amp;gt;= 0 &amp;amp;&amp;amp; r * 6 &amp;lt;= 2 ) ? 0 : ( r * 6 &amp;gt;= 3 &amp;amp;&amp;amp; r * 6  &amp;lt;= 5) ? 1 : ( 1 - abs ( ( r * 6 ) % 2 - 1 ) )&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
But better:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r: from 0 to 1&lt;br /&gt;
g: 1&lt;br /&gt;
b: 1&lt;br /&gt;
&lt;br /&gt;
colorspace in HSV out sRGB&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Quick Tips ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#knobs and values of a node&lt;br /&gt;
print(nuke.selectedNode())&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Create proxy from File with reformat ===&lt;br /&gt;
exr to png&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#creates RGBA8bit PNG with .5 scale and write next to file with .png extension. So /path/to/file.exr.png&lt;br /&gt;
for node in nuke.selectedNodes():&lt;br /&gt;
    if node.Class() == &amp;#039;Read&amp;#039;:&lt;br /&gt;
        readPath = node[&amp;#039;file&amp;#039;].evaluate()&lt;br /&gt;
        reformat = nuke.nodes.Reformat(inputs=[node],type=2,scale=.5)&lt;br /&gt;
        write = nuke.nodes.Write(inputs=[reformat],channels=&amp;#039;rgba&amp;#039;,file=readPath+&amp;#039;.png&amp;#039;,file_type=&amp;#039;png&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
        node[&amp;#039;selected&amp;#039;].setValue(0)&lt;br /&gt;
        write[&amp;#039;selected&amp;#039;].setValue(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
png to exr&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#reads to EXR&lt;br /&gt;
for node in nuke.selectedNodes():&lt;br /&gt;
    if node.Class() == &amp;#039;Read&amp;#039;:&lt;br /&gt;
        readPath = node[&amp;#039;file&amp;#039;].evaluate()&lt;br /&gt;
        #reformat = nuke.nodes.Reformat(inputs=[node],type=2,scale=.5)&lt;br /&gt;
        write = nuke.nodes.Write(inputs=[node],channels=&amp;#039;rgba&amp;#039;,file=readPath+&amp;#039;.exr&amp;#039;,file_type=&amp;#039;exr&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
        node[&amp;#039;selected&amp;#039;].setValue(0)&lt;br /&gt;
        write[&amp;#039;selected&amp;#039;].setValue(1)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Contact Sheet Ordered From Lasso-Selected ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# takes a selection of read nodes, and places them in a contact sheet according to their position&lt;br /&gt;
# in the node graph&lt;br /&gt;
# first input of contact sheet determines text &amp;amp; text positions, it defaults to the read image name&lt;br /&gt;
&lt;br /&gt;
# to do: auto number the Contact sheet&lt;br /&gt;
&lt;br /&gt;
from random import random&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def linkKnobs(sourceNode, destNode, knobs = []):&lt;br /&gt;
    for knob in knobs:&lt;br /&gt;
        for idx, item in enumerate(sourceNode[knob].array()):&lt;br /&gt;
            expression =  sourceNode.name()+&amp;#039;.&amp;#039;+str(knob)+&amp;#039;.&amp;#039;+str(idx)&lt;br /&gt;
            destNode[knob].setExpression(expression,idx)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
nodes = nuke.selectedNodes()&lt;br /&gt;
nodeList = []&lt;br /&gt;
minmaxX = [1000000,-1000000]&lt;br /&gt;
minmaxY = [1000000,-1000000]&lt;br /&gt;
averagePosition = [0,0]&lt;br /&gt;
counter = 0&lt;br /&gt;
&lt;br /&gt;
for node in nodes:&lt;br /&gt;
    counter = counter + 1&lt;br /&gt;
    nodePos = [node[&amp;#039;xpos&amp;#039;].value(),node[&amp;#039;ypos&amp;#039;].value()]&lt;br /&gt;
    averagePosition = [averagePosition[0]+nodePos[0],averagePosition[1]+nodePos[1]]&lt;br /&gt;
    minmaxX = [min(minmaxX[0],nodePos[0]),max(minmaxX[1],nodePos[0])]&lt;br /&gt;
    minmaxY = [min(minmaxY[0],nodePos[1]),max(minmaxY[1],nodePos[1])]&lt;br /&gt;
    nodeList.append([node,nodePos[0],nodePos[1]])&lt;br /&gt;
&lt;br /&gt;
averagePosition = [averagePosition[0]/(counter*1.0),averagePosition[1]/(counter*1.0)]&lt;br /&gt;
horizontalSort = True&lt;br /&gt;
&lt;br /&gt;
if minmaxX[1]-minmaxX[0] &amp;gt; minmaxY[1]-minmaxY[0]:&lt;br /&gt;
    horizontalSort = True&lt;br /&gt;
    nodeList.sort(key=lambda x: x[1])&lt;br /&gt;
else:&lt;br /&gt;
    horizontalSort = False&lt;br /&gt;
    nodeList.sort(key=lambda x: x[2])&lt;br /&gt;
&lt;br /&gt;
textNodes = []&lt;br /&gt;
for array in nodeList:&lt;br /&gt;
&lt;br /&gt;
    textNode = nuke.nodes.Text2(inputs=[array[0]],xjustify=&amp;#039;left&amp;#039;,yjustify=&amp;#039;bottom&amp;#039;,box=&amp;#039;15 15 3000 1000&amp;#039;)&lt;br /&gt;
    textNodes.append(textNode)&lt;br /&gt;
&lt;br /&gt;
    if horizontalSort:&lt;br /&gt;
        textNode.setXpos( int(array[0][&amp;#039;xpos&amp;#039;].value()) )&lt;br /&gt;
        textNode.setYpos( int(array[0][&amp;#039;ypos&amp;#039;].value() + 200.0) )&lt;br /&gt;
    else:&lt;br /&gt;
        textNode.setXpos( int(array[0][&amp;#039;xpos&amp;#039;].value() + 200.0) )&lt;br /&gt;
        textNode.setYpos( int(array[0][&amp;#039;ypos&amp;#039;].value() + 20 ) )&lt;br /&gt;
    nuke.autoplaceSnap(textNode)&lt;br /&gt;
&lt;br /&gt;
#ratio = nodeList[0][0].width()/nodeList[0][0].height()&lt;br /&gt;
#print ratio&lt;br /&gt;
#print len(nodeList)&lt;br /&gt;
cs = nuke.nodes.ContactSheet(inputs=textNodes)&lt;br /&gt;
&lt;br /&gt;
if horizontalSort:&lt;br /&gt;
    cs.setXYpos(int(averagePosition[0] + 0),int(averagePosition[1] + 350))&lt;br /&gt;
else:&lt;br /&gt;
    cs.setXYpos(int(averagePosition[0] + 350),int(averagePosition[1] + 0))&lt;br /&gt;
&lt;br /&gt;
nuke.autoplaceSnap(cs)&lt;br /&gt;
&lt;br /&gt;
controlText = textNodes[0]&lt;br /&gt;
controlText.knob(&amp;#039;message&amp;#039;).setValue(&amp;#039;[lindex [split [lindex [split [knob [topnode].file] .] 0] /] end]&amp;#039;)&lt;br /&gt;
controlText.knob(&amp;#039;tile_color&amp;#039;).setValue(int(&amp;#039;%02x%02x%02x%02x&amp;#039; % (random()*255,random()*255,random()*255,1),16))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for n in textNodes[1:]:&lt;br /&gt;
&lt;br /&gt;
    n.knob(&amp;#039;message&amp;#039;).setValue(&amp;#039;[expr [knob &amp;#039;+controlText.name()+&amp;#039;.message]]&amp;#039;)&lt;br /&gt;
    linkKnobs(controlText,n,[&amp;#039;box&amp;#039;,&amp;#039;global_font_scale&amp;#039;,&amp;#039;yjustify&amp;#039;,&amp;#039;xjustify&amp;#039;,&amp;#039;font_size&amp;#039;,&amp;#039;font_width&amp;#039;,&amp;#039;font_height&amp;#039;,&amp;#039;kerning&amp;#039;,&amp;#039;tracking&amp;#039;,&amp;#039;baseline_shift&amp;#039;,&amp;#039;leading&amp;#039;,&amp;#039;translate&amp;#039;,&amp;#039;rotate&amp;#039;,&amp;#039;scale&amp;#039;,&amp;#039;center&amp;#039;])&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Change Read file locations with a text file ===&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/OyXUaft.png&lt;br /&gt;
&lt;br /&gt;
Poor man&amp;#039;s read node manager if you don&amp;#039;t have Shotgun. Basically opens up a temp text file with the selected &amp;#039;Read&amp;#039; nodes filepaths where you can easily search and replace paths. Non-read nodes won&amp;#039;t be affected.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import tempfile, os&lt;br /&gt;
&lt;br /&gt;
reads = []&lt;br /&gt;
for node in nuke.selectedNodes():&lt;br /&gt;
    if node.Class() == &amp;#039;Read&amp;#039;:&lt;br /&gt;
        npath = node[&amp;#039;file&amp;#039;].getText()&lt;br /&gt;
        reads.append([node,npath])&lt;br /&gt;
paths = [item[1] for item in reads]&lt;br /&gt;
paths = &amp;quot;\n&amp;quot;.join(paths)&lt;br /&gt;
&lt;br /&gt;
fp = tempfile.NamedTemporaryFile(delete=False,suffix=&amp;quot;.txt&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
fp.write(paths)&lt;br /&gt;
&lt;br /&gt;
fp.flush()&lt;br /&gt;
&lt;br /&gt;
if os.name == &amp;#039;nt&amp;#039;:&lt;br /&gt;
    os.startfile(fp.name)&lt;br /&gt;
else:&lt;br /&gt;
    os.system(&amp;#039;xdg-open &amp;#039;+fp.name)&lt;br /&gt;
if nuke.ask(&amp;#039;Press No to cancel or \nPress Yes if you have finished editing and saved the temp file&amp;#039;):&lt;br /&gt;
    f = open(fp.name, &amp;quot;r&amp;quot;)&lt;br /&gt;
    newpaths = f.read().split(&amp;#039;\n&amp;#039;)&lt;br /&gt;
    for i in range(len(reads)):&lt;br /&gt;
        if reads[i][1] != newpaths[i]:&lt;br /&gt;
            reads[i][0][&amp;#039;file&amp;#039;].setValue(newpaths[i])&lt;br /&gt;
        else:&lt;br /&gt;
            print(reads[i][0].name()+&amp;quot; no change detected.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Automatically merge files into single channel ===&lt;br /&gt;
&lt;br /&gt;
https://i.imgur.com/bE5OYQu.png&lt;br /&gt;
&lt;br /&gt;
If you didn&amp;#039;t toggle multi-channel exr you big dummy&lt;br /&gt;
&lt;br /&gt;
This might bug around &amp;#039; simplename = strpath.split(&amp;quot;/&amp;quot;).pop().split(&amp;quot;_v0&amp;quot;)[0].split(&amp;quot;_&amp;quot;).pop() &amp;#039; since it was specific to my project (this line figures out the channel name)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def sortAccordingToNodeGraphPosition(nodes):&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;sorts a node list according to their graph position. Hack-ish but works (?)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
    nodeList = []&lt;br /&gt;
    minmaxX = [1000000,-1000000]&lt;br /&gt;
    minmaxY = [1000000,-1000000]&lt;br /&gt;
    averagePosition = [0,0]&lt;br /&gt;
    counter = 0&lt;br /&gt;
    &lt;br /&gt;
    for node in nodes:&lt;br /&gt;
        counter = counter + 1&lt;br /&gt;
        nodePos = [node[&amp;#039;xpos&amp;#039;].value(),node[&amp;#039;ypos&amp;#039;].value()]&lt;br /&gt;
        averagePosition = [averagePosition[0]+nodePos[0],averagePosition[1]+nodePos[1]]&lt;br /&gt;
        minmaxX = [min(minmaxX[0],nodePos[0]),max(minmaxX[1],nodePos[0])]&lt;br /&gt;
        minmaxY = [min(minmaxY[0],nodePos[1]),max(minmaxY[1],nodePos[1])]&lt;br /&gt;
        nodeList.append([node,nodePos[0],nodePos[1]])&lt;br /&gt;
    &lt;br /&gt;
    averagePosition = [averagePosition[0]/(counter*1.0),averagePosition[1]/(counter*1.0)]&lt;br /&gt;
    horizontalSort = True&lt;br /&gt;
    &lt;br /&gt;
    if minmaxX[1]-minmaxX[0] &amp;gt; minmaxY[1]-minmaxY[0]:&lt;br /&gt;
        horizontalSort = True&lt;br /&gt;
        nodeList.sort(key=lambda x: x[1])&lt;br /&gt;
    else:&lt;br /&gt;
        horizontalSort = False&lt;br /&gt;
        nodeList.sort(key=lambda x: x[2])&lt;br /&gt;
    &lt;br /&gt;
    sortedList = [node for node, x,y in nodeList]&lt;br /&gt;
    return sortedList&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
selReads = nuke.selectedNodes()&lt;br /&gt;
selReads = sortAccordingToNodeGraphPosition(selReads)&lt;br /&gt;
shuffleInputs = []&lt;br /&gt;
selReadslen = len(selReads)&lt;br /&gt;
for i in range(selReadslen):&lt;br /&gt;
&lt;br /&gt;
    #curRead = selReads[selReadslen-1-i]&lt;br /&gt;
    curRead = selReads[i]&lt;br /&gt;
    strpath = curRead[&amp;#039;file&amp;#039;].value()&lt;br /&gt;
    simplename = strpath.split(&amp;quot;/&amp;quot;).pop().split(&amp;quot;_v0&amp;quot;)[0].split(&amp;quot;_&amp;quot;).pop()&lt;br /&gt;
    #goes from &amp;#039;D:/longpath/folder/v006/superlongname_360_beauty_v006.%04d.exr&amp;#039; to  &amp;#039;beauty&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if i &amp;gt; 0:&lt;br /&gt;
        shuffle = nuke.nodes.ShuffleCopy()&lt;br /&gt;
        shuffleInputs.append(shuffle)&lt;br /&gt;
        shuffle.setInput(0, shuffleInputs[i-1])&lt;br /&gt;
        shuffle.setInput(1, curRead)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
        cmd = &amp;quot;add_layer {%s &amp;quot; % simplename&lt;br /&gt;
        for each in [&amp;quot;r&amp;quot;, &amp;quot;g&amp;quot;, &amp;quot;b&amp;quot;, &amp;quot;a&amp;quot;]:&lt;br /&gt;
            cmd += &amp;quot;%s.%s &amp;quot; % (simplename, each)&lt;br /&gt;
        &lt;br /&gt;
        cmd += &amp;quot;}&amp;quot;&lt;br /&gt;
        &lt;br /&gt;
        #set using tcl can&amp;#039;t figure out python for this&lt;br /&gt;
        nuke.tcl(cmd)&lt;br /&gt;
        shuffle[&amp;quot;label&amp;quot;].setValue(&amp;quot;[knob this.out]&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;out&amp;quot;].setValue(simplename)&lt;br /&gt;
        shuffle[&amp;quot;out2&amp;quot;].setValue(&amp;#039;rgba&amp;#039;)&lt;br /&gt;
        shuffle[&amp;quot;red&amp;quot;].setValue(&amp;quot;red&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;green&amp;quot;].setValue(&amp;quot;green&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;blue&amp;quot;].setValue(&amp;quot;blue&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;alpha&amp;quot;].setValue(&amp;quot;alpha&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;black&amp;quot;].setValue(&amp;quot;red2&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;white&amp;quot;].setValue(&amp;quot;green2&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;red2&amp;quot;].setValue(&amp;quot;blue2&amp;quot;)&lt;br /&gt;
        shuffle[&amp;quot;green2&amp;quot;].setValue(&amp;quot;alpha2&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    else:&lt;br /&gt;
        shuffleInputs.append(curRead)&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Automatically extract channels ===&lt;br /&gt;
source: http://www.muttsy.net/blog/2011/10/20/shuffle-out-all-channels/&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import os&lt;br /&gt;
&lt;br /&gt;
createWrite = False&lt;br /&gt;
nodes = nuke.selectedNodes()&lt;br /&gt;
for node in nodes:&lt;br /&gt;
    if node.Class() == &amp;#039;Read&amp;#039;:&lt;br /&gt;
        channels = node.channels()&lt;br /&gt;
        layers = list( set([channel.split(&amp;#039;.&amp;#039;)[0] for channel in channels]) )&lt;br /&gt;
        layers.sort()&lt;br /&gt;
        #readPath = node[&amp;#039;file&amp;#039;].evaluate()&lt;br /&gt;
        readPath = os.path.splitext(readPath)[0]&lt;br /&gt;
        print(readPath)&lt;br /&gt;
        if &amp;#039;rgba&amp;#039; in layers:&lt;br /&gt;
            layers.remove(&amp;#039;rgba&amp;#039;)&lt;br /&gt;
        for layer in layers:&lt;br /&gt;
            shuffleNode = nuke.nodes.Shuffle(label=layer,inputs=[node])&lt;br /&gt;
            shuffleNode[&amp;#039;in&amp;#039;].setValue( layer )&lt;br /&gt;
            shuffleNode[&amp;#039;postage_stamp&amp;#039;].setValue(True)&lt;br /&gt;
            if createWrite:&lt;br /&gt;
                writeNode = nuke.nodes.Write(label=layer,inputs=[shuffleNode])&lt;br /&gt;
                writeNode[&amp;#039;file&amp;#039;].value = readPath+layer+&amp;#039;.png&amp;#039;&lt;br /&gt;
                print(readPath+layer+&amp;#039;.png&amp;#039;)&lt;br /&gt;
    else:&lt;br /&gt;
        pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Auto write new folders===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
for w in nuke.allNodes(&amp;quot;Write&amp;quot;):&lt;br /&gt;
w.knob(&amp;quot;beforeRender&amp;quot;).setValue(&amp;quot;import os\nif not os.path.isdir(os.path.dirname(nuke.thisNode()[&amp;#039;file&amp;#039;].evaluate())):\n  os.makedirs(os.path.dirname(nuke.thisNode()[&amp;#039;file&amp;#039;].evaluate()))&amp;quot;)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Category:Nuke]]&lt;/div&gt;</summary>
		<author><name>Bernie</name></author>
	</entry>
</feed>