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)) 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.
A while ago I’ve blogged about the planar tracking features of Syntheyes and I’ve finally made some updates to the Fusion exporter to support them. In addition to that, I’ve played around with the Python support in Syntheyes and I’ve written a script that can create and update (!) a comp in a running Fusion instance. This saves you a lot of hassle if you have tweaked a matchmove or added trackers to a point cloud but you don’t want to export a composition from scratch!
The package consists of three scripts: an advanced exporter for Syntheyes, a Python script for Syntheyes that is able to create and update tools from a matchmove (camera, point cloud, planar trackers) and a small tool script for Fusion that sets up a Syntheyes project from a selected Loader. Syntheyes Pro 2013.11 or later required for the Python scripts. Readme included.
The Fusion6 exporter is based on the Fusion5 script that ships with Syntheyes and has been updated in many ways:
- support for stereo camera pairs
- support for planar trackers (with or without planar export preparation script)
- work area (timeline) options as in AfterEffects exporter
- Create locked cameras to prevent their accidental modifications
- Added project info to comp’s comments tab and footage name to camera’s comments
- various fixes like paths and obj meshes
- convert paths to a Windows format when running Syntheyes on Mac/Linux
Remember when I posted photos of the Shanghai Financial Center? That iconic skyscraper that looks like a bottle opener:
Well, they are building an even bigger skyscraper next to it. When I was in Shanghai it was just an empty construction site. Now it’s almost finished.
And here’s some Russian guys climbing it: