You're currently only viewing posts tagged "Nuke". See all posts instead.

Adding Layers and Channels in Nuke

If you need to create new layers in Nuke via Python, here’s the proper syntax:

nuke.tcl("add_layer", "newLayer newLayer.red newLayer.green newLayer.blue")

That was a bit hard to find in the docs as well as online and there’s some weird behavior (at least in Nuke 8) when this is called in a script vs typing it into the scripting console.

For example, the tcl input (“x” hotkey) requires you to enter the command as “add_layer {myLayer red green blue}” and it reminds you of the curly braces syntax in case you do it incorrectly. The .tcl method in Python, however, mustn’t contain curly braces.

Moreover, nuke.tcl requires you to spell out the rgb channels in dot format. If you just use “red green blue” Nuke will create a layer called “other” for some weird reason and probably crash sooner or later. It only does this in Python scripts though. Not in the scripting console.

You might have noticed that I’m calling a TCL command via Python. There’s also a native way: nuke.Layer(). Just like its tcl counterpart it requires you to spell out the channel names – even if the official docs say otherwise:

nuke.Layer("newLayer", ["newLayer.red", "newLayer.green", "newLayer.blue"])

Trolling International Relations via VFX

This is the story of a great hoax no matter what the true story is: after the German media has made a fuss about a 2013 video of the Greek treasury secretary Varoufakis flipping the finger, a small TV show has claimed that the video is fake and that they have doctored it (enable English subtitles). At the end of my post I’ll demonstrate why I think they are making this up.

 

A bit of context:

German’s biggest yellow press newspaper has been spewing tirades and stirring hatred towards Greece for years now. By now, viewing Greeks as lazy thieves of hard-earned German monies is basically ingrained in our national narrative of Europe; as shameful as it is.

The team of a small late night show claims to have trolled the media by inserting the obscene gesture and seeding the video to Youtube. But did they? They might have doctored the video the other way around for their show to remove the gesture of Varoufakis and make a point about the current German mindset.

From a technical point of view, either theory is plausible. I’ve done VFX to replace body parts myself and that section of the Nuke comp that they’re showing makes some sense (except for the motion blurred grid they used as a making-of effect). It would certainly possible to make Varoufakis raise his middle finger for a few frames.

Nuke Varou Comp

But it would be an equal amount of work to remove the gesture: retime, freeze and matchmove his torso to postpone the upwards motion of his arm by a few frames, then transition back to the original footage.

whatthefuckis

They should release “whatthefuckis_v3.nk” and the footage to remove all doubts 🙂

 

To those who are amazed by what you can do with technology these days: that stuff has not only been possible for 20+ years (see Jurassic Park’s stunt double face swap which was still a bit rough around the edges). It has been done seamlessly on all kinds of motion pictures for quite a while.

Analysis:

So can we find out which clip is real just by comparing both versions? Yes. I think the finger is real (side note: and I couldn’t care less…) and here’s why:

Let’s start with the obvious. The idea that you would fake this by employing an actor who looks like Varoufakis and making him wear a green full-body suit except for his hand and collar is ridiculous.

The cliché of green spandex suits

The cliché of green spandex suits

It’s playing with the general public’s idea of how green-screen photography works and it has been spoofed a lot of times already, for example by MADtv years ago and anotherGerman TV show more recently.

But let’s look at the hard facts of the footage at hand. Here’s a frame-by-frame comparison of both clips next to each other. No matter which version is real, they did a great job.

 

To fake the left version (the flipped finger), they would have had to replace the right side of his torso to get rid of the lowered arm and during (what would in this case be) the arm’s real upwards motion. That’s much more than just pasting a new hand on top of Varoufakis as they make us believe during the making-of. That’s a great comp job (if it were true).

By the way: the nature of the shirt he’s wearing might make doctoring this footage easier. Wrinkles pop up and vanish due to the tiniest motions of his body so you can hide masks and transitions better than you might think.

If the right version – without the middle finger – was fake, they would have had to freeze, replace and/or morph a large part of Varoufaki’s torso and parts of his collar to get rid of the raised hand for an extended period of time, all while Varoufaki’s face keeps moving/talking. That’s great comp job in this case as well.

But here’s the real deal: They would also have to mess with the other hand that is holding the microphone! And they did.

Here’s how to spot the fake:

You can see in the left shot (the one that I think is genuine) that there’s a shadow running over the mic while Varoufakis raises his hand. On the left side (the one that I think is fake) the whole hand and microphone area is excibiting a weird wobbling motion that starts as soon as they had to retime/freeze his torso and stops as soon as he lowers his arm.

To me, this is a sign of doctoring. A side effect of the warping they had to do to match a non-shadowed microphone on top of the real footage.

And then there’s the artifact which is the ultimate clue in my opinion.

mic_hand_anim

Right after his hand has moved down, they transition from their fake clean plate back to the real microphone. But the cable has been twisted ever so slightly while Varoufakis was flipping the finger that you can see the blending of two versions of the cable.

Verdict:

The finger is real. The VFX artist(s) did a great job to undo this gesture and the show is (successfully) trolling the media by making them think they fell for a doctored video. ZDF neo and its host Jan Böhmermann are successful in making the general public question the way they get enraged by unimportant videos that were taken out of context.

Further reading: The Ems Dispatch, a purposefully edited document that played a part in starting the Franco-Prussian war in 1870.

Nuke Autolabel Magic

Nuke has some powerful ways to define how nodes are labeled in the DAG. And they make for some fun ways to augment your gizmos. By default, Nuke ships with a script called autolabel.py which takes care of labeling all the nodes in various ways:

various autolabels in Nuke

pictured: various autolabels

  • the node’s name (obviously)
  • a channel combo like “green blue” in case the node doesn’t simply process RGBA.
  • the value of a node’s “output” knob, if such a knob exists (try adding one as a user knob to see this magic label)
  • the current file name of a read node
  • the merge mode of a merge node (sic!)
  • the text of a node’s label knob
  • and probably much more…

You can, however, write your own autolabel function for either a specific node or a whole class of nodes. The downside is that you lose all of the default autolabels if you don’t reimplement them yourself.

autolabel knob:

Every tool has a hidden knob called autolabel that can hold a Python expression. Its return value is used to label the node. So let’s see how this works. Create a node (mine’s called “Blur3” from now on) and open the scripting console panel. Type:

autoLabel = "abc"
nuke.toNode("Blur3")['autolabel'].setValue(autoLabel)

autolabel2

Of course this fails. But you see clearly that Nuke tries to execute your autolabel string as a Python expression. So let’s start with a basic example:

autoLabel = "nuke.thisNode().name()"
nuke.toNode("Blur3")['autolabel'].setValue(autoLabel)

This works. Note how the command nuke.thisNode() is used to refer to the node whose label is currently being processed. Just using the node’s name as a label is the most basic thing to do. As the presence of an autolabel string will override Nuke’s default behavior, you won’t get anything else that a blur node might usually have (channel info and custom label value). Also note how this label is only applied to “Blur3”. Any other blur nodes will continue to use Nuke’s default autolabel.py behavior. But these autolabel expressions can get more useful, complex and powerful:

autolabel4

Here I’m changing the label based on the value of another knob. Python doesn’t have the C-like syntax “expression ? yes : no” which would be really handy in this case. But it has something similar which I wasn’t aware of before a fellow TD showed this to me:

("some string" if expression else "another string")

This will help us build even more powerful autolabel expressions. Note how all of this is still one single string so I’m using single quotes inside it and I need to escape all newline characters as \\n. A single backslash would cause a line break in the code itself instead of the string. What’s still missing is the label knob which Nuke adds to all nodes by default. We need to implement this ourselves and it’s a bit tricky because you need to add a line break for this only if there actually is a label.

autoLabel = "nuke.thisNode().name() + (' big!' if nuke.thisNode()['size'].value()>100 else ' small') + ('\\n'+nuke.thisNode()\['label'].value() if nuke.thisNode()['label'].value() else '')"
nuke.toNode("Blur3")['autolabel'].setValue(autoLabel)

autolabel5

The further you go the more complex all of this gets. So why would you use the autolabel knob when Nuke has autolabel event handlers as well?

  • the knob affects a single tool, not a whole class of nodes
  • that string will get copy&pasted around with the node, autolabel event handlers remain separate from your nuke scripts (the latter has its advantages of course when it comes to maintainability and preventing your pipeline’s code from leaving your company)
  • the knob can be used with groups and node presets. All groups share the same class so it’s not possible to single one of them out.

autolabel event handlers:

To finish this tutorial, here’s the autolabel event handler that corresponds to the knob monstrosity above. It needs to be placed into your menu.py (or any python modules that are imported). You can have multiple autolabel handlers so you don’t need to cover all node classes in one function. Nuke calls all of them in a row and uses the first one that doesn’t return None.

def BlurLabel():
    n = nuke.thisNode()
    if n.Class() == "Blur":
        autoLabel = n.name() + (' big!' if n['size'].value()>100 else ' small')
        if n['label'].value():
            autoLabel = autoLabel + '\n' + n['label'].value()
        return autoLabel
 
nuke.addAutolabel(BlurLabel)

autolabel6

Good things come to those who wait?

Fusion 7 is close to a release. It will go beyond Nuke in some aspects (great stereo tools bundled for free and an impressive-looking scripting console/debugger), finally catch up in other parts (a modular GUI and UV unwrapping in 3D space) and contain lots of fixes and overdue improvements.

Fusion? You know, the compositing software next to Nuke?

Fusion has always beaten Nuke in terms of speed and versatility in a broadcast / commercials area. But eyeon software‘s weird and cryptic marketing, dated website, their unwillingness to communicate a roadmap combined with the fact that Fusion hasn’t been updated for close to two years has pissed off their user base and made most of the industry switch to the software that initially only high end VFX shops were using. There they can profit from a large freelancer base, lots of talented R&D people, 3rd party training and a company that is upfront about future developments and schedules.

And if you’re doing high end VFX you’re just served well with Nuke, no matter how much faster Fusion would be. The motion graphics crowd on the other hand is still served well by AfterEffects. By now, Fusion’s at the bottom of a downward spiral of “less users – less interest of 3rd parties – less tutorials and plugins – less users” that I think is hard to recover from. Eyeon’s latest efforts to tap into the Avid community seem to bear fruits though but the GUI and feature needs of those folks clearly clash with regular compositing artists.

But here’s eyeon software, back from the dead so to speak, with at least a changelog and some videos about what we can expect in Fusion 7. I’ll talk more about the release once I’ve put it to the test myself.

what's newFor now, the “What’s new” PDF instills the feeling that eyeon’s marketing is still bonkers. They start up with the tiniest change. The cool stuff is at the end of the PDF. And it actually touts the standard multi-document (MDI) style of Windows applications as a new feature. Seriously folks, Fusion has had that interface for years and nobody loves it because a crash on one comp pulls down the whole application and nobody has the screen space to lay out two comps side-by-side anyways. This reeks of “grasping at straws” to inflate the feature list which wouldn’t be necessary at all. Fusion 7 promises new 3D tools, UV unwrapping, (screen space) Ambient Occlusion and many GUI improvements and it will include Dimension by default – eyeon’s stereoscopic and optical flow toolset that gives Occula a run for its money. It also seems as if I can update some of my Fuses and macros with new API features.

Stay tuned for a thorough review of different aspects of the Fusion update.

Patching Your Pipeline

Recently, our studio’s file server started failing randomly. We lost Nuke scripts and we also lost the autosave files that Nuke creates in the same directory. Of course there are ways to deal with that on lower levels but I needed a quick fix that I could deploy without dealing with infrastructure and file system journals. Fortunately, Nuke provided the means to do that. I managed to redirect autosaves to each artist’s local drive without even accessing their machines. Here’s how:

Nuke has a bunch of callbacks that you can use. And it also has some that relate to autosaves:

  • AutoSaveFilter (called whenever Nuke wants to write to an autosave file)
  • AutoSaveRestoreFilter (called whenever it wants to check or read an autosave during startup)
  • AutoSaveDeleteFilter (called before an autosave gets deleted).

All of these functions receive the file name of the autosave that Nuke would use if you hadn’t installed any event handlers. The expected return value is a modified file name that it will actually use.

The whole idea is simple: diverting autosaves whose paths match a certain pattern (I only want to catch those that would have been saved on our file server) to a clone of the server’s folder structure on the artist’s local drive. We’re running Linux so I chose ~/Documents/NukeAutosaves as a location.

As an extra failsafe against data loss I made a copy of an autosave right before Nuke deletes it. This makes sure that each artist gets an automatic copy his .nk script on his local drive. This script may not be the same as the .nk file that is saved on the server, but since it is identical to the last autosave, it’s definitely a helpful backup.

Here’s the Python code that you need to paste into your init.py or include it as a separate module (which I recommend):

import os, re, shutil
import nuke
 
def onAutoSave(filename):
  """Build local autosave file name for saving."""
  localfilename = os.path.expanduser(re.sub(r"/PATH/TO/SERVER/", r"~/Documents/NukeAutosave/", filename, re.IGNORECASE))
  localdir = os.path.dirname(localfilename)
  if not os.path.isdir(localdir):
    os.makedirs(localdir)
  return localfilename
 
def onAutoSaveRestore(filename):
  """Build local autosave file name for restoration."""
  return os.path.expanduser(re.sub(r"/PATH/TO/SERVER/", r"~/Documents/NukeAutosave/", filename, re.IGNORECASE))
 
def onAutoSaveDelete(filename):
  """Create a backup copy before deleting an autosave."""
  # only delete untiled autosave
  if nuke.root().name() == 'Root':
    return filename
  # build local autosave file name
  localfilename = os.path.expanduser(re.sub(r"/PATH/TO/SERVER/", r"~/Documents/NukeAutosave/", filename, re.IGNORECASE))
  # before Nuke deletes it, make a backup copy (without the .autosave extension)
  try:
    if os.path.isfile(localfilename):
      shutil.copy2(localfilename, os.path.splitext(localfilename)[0])
  except Exception as e:
    print "Exception thrown in onAutoSaveDelete(): %s" % e
  return localfilename
 
def init():
  nuke.addAutoSaveFilter( onAutoSave )
  nuke.addAutoSaveRestoreFilter( onAutoSaveRestore )
  nuke.addAutoSaveDeleteFilter( onAutoSaveDelete )
 
init()

Our file server was of course fixed soon after I had deployed this hotfix. But I have left it in our pipeline since then because it solves another autosave problem: bogus autosaves created by other users.

Whenever someone else opens your script without saving (maybe a supervisor or just another artist who needs to borrow part of your setup) he’ll leave behind an autosave. These files are potentially dangerous. Nuke will ask you to restore from this autosave but what if it contains changes that mess with your script or even break it? The guy who previously opened your comp didn’t mean any harm and he didn’t save his changes. But now you’ve restored his autosave and by subsequently hitting “save” you might have damaged your script permanently.

The hotfix I have shown above will divert all autosaves to local machines. So when you open a script, Nuke will never find an autosave that somebody else has created or left behind.

TCL string magic

Here’s another small expression for Nuke. I wanted to burn in a read node’s current frame number using a Text node. It’s easy to get the current image’s source file name from the input’s metadata. But can you extract the frame number from a string like “/server/path/filename.01234.exr”?

Sure! This expression splits the file name into parts separated by the dot character. The 2nd part (index 1 in tcl) is the number we’re looking for:

[lindex [split [metadata input/filename] "."] 1]

A text node with this expression is useful for Hiero burn-ins by the way…

split_frame_number

Nuke Python Expression Switch

Nuke’s Python expression syntax can be shorter and more readable than tcl.

Imagine, you want to use a switch to toggle part of your comp on or off on certain frames – maybe to fix artifacts in a 3D pass. Instead of animating a switch’s input or a tool’s mix slider between 0 and 1 you could use an expression:

frame == 1025

This will set the knob to 1 on frame 1025 and to 0 anywhere else. An expression like that also works if you want to enable that knob on several frames, but it gets increasingly unreadable:

frame == 1025 || frame == 1072 || frame == 1074

TCL expression switch

A Python expression is shorter and easier to extend. Enable the Py button in the expression popup and there you go:

nuke.frame() in [1025,1072,1074]

Python expression switch