Showing posts with label script. Show all posts
Showing posts with label script. Show all posts
Bookmark and Share

Often times I find myself moving Nuke scripts back and forth between my computer at home and the labs in school. If you work on multiple computers with your Nuke scripts, you've more than likely experienced broken Read Nodes.



But fear not young padawan! There are ways to avoid spending 15 minutes redirecting Nuke to all your files. I've come across a couple of scripts to fix your Read Nodes, but by far the most jaw-droppingly easy one comes from The Foundry itself. If you haven't checked it out yet, the Nuke Master Class last January was extremely beneficial and I highly recommend everyone to check out their videos and source files.

In their Python videos, they quickly demonstrate fixPaths.py, which attempts to automatically fix the paths of all the missing files in your Nuke script. Here's a little excerpt from the second Python video showing the FixPaths script in action:



Again, please please please, I urge you to go visit the Nuke Master Class and view the entire video in higher res. It will be worth your while, I promise.

-------------------------------------------

This second method I learned from a good friend of mine, Devank, who put together a PDF based on another tutorial from The Foundry. You can download his original PDF here.

The rundown of his interpretation goes a little bit like this:

  1. Create a NoOp node and set its name to Path.



  2. Right-click on the NoOp node in the Properties panel and select Manage User Knobs. Add a Filename knob and rename it to Project_Path.


  3. Enter or browse to the path of your project directory.


  4. Now all you have to do is copy and paste this little code into all your Read nodes before the filename to insure it links to the Project directory.

    [value Path.Project_Path]




  5. Now whenever you switch computers, all you need to do is change the Project path in the NoOp node and your Read nodes should fix themselves.



edit post

Fake Highlight Rotation View Comments

2:44 PM by , under , , , ,

Bookmark and Share

A friend of mine is currently working on a project in which there is a ball rolling on the floor and he needs to move the highlight in order to correspond to a light source in the distance. I came up with a quick solution, and I thought I'd share it in case you cross upon something similar, because I feel that this is something quite common, but I wasn't able to find anything on the net. You can download the AEP file here if needed.

Here is the result:


Basically, I created a null that acted as the fake position of our light. Then, I used this null's position to calculate the distance from the highlight on the X and Y axes and theoretically made a right triangle. Using each axis information, I plugged it all into an inverse tangent equation to give me the correct angle that I wanted. Then I just added a multiplier to increase/decrease the amount of rotation.

In this AEP file, I have 4 layers. The ground, the ball, the reflection, and the null. I animated the ball moving around in an arc that roughly imitates my friend's animation.

Want you want to do next is make sure that the Anchor Point for the highlight is in the center of the ball, that way when we rotate it, it will do so inside the ball. Then make sure to parent the highlight to the ball. Afterwards you want to Alt-Click on the Rotation stopwatch in the highlight layer to open up an expression box and type in the following code:


adjc = sub(thisComp.layer("nullLightSource").transform.position[0],thisComp.layer("ball").transform.position[0])
opp = sub(thisComp.layer("nullLightSource").transform.position[1],thisComp.layer("ball").transform.position[1])

sidesratio = div(opp,adjc)

inversetan = Math.atan(sidesratio)*25


Let's break this code down a little. The variable adjc takes the X axis info from the null called "nullLightSource" and subtracts it from the X pos of the layer called "ball". Similarly, opp takes the difference from the Y info. sidesratio then plugs these two correctly into the inverse tangent equation Math.atan().
Then I added a multiplier of 25 at the end of inversetan simply because it looked good.

And voila! You now have a highlight rotating based upon the position of a null. I'm sure somebody can come up with an even cooler application to this, maybe a giant axe blade attached to the end of a pendulum?



edit post

Render Sound in Nuke Part 2 View Comments

11:19 PM by , under , , , , ,

Bookmark and Share

Earlier this week, I posted a super basic beginner's tutorial intro into manipulating scripts inside of Nuke, and gave you a handy little code that played a sound when your render was finished. Well, after a little trial and error, I managed to come up with a script that attaches itself to Nuke's Write node and adds a custom tab with the 'Render with Sound' function. I tried to mimic the original Write node's interface, but unfortunately due to the dynamic nature of the Write node and the various file extensions and video codecs that are interactively added, it tends to switch back and forth between tabs. Although, once you set your file extension and codec, you can switch back to the 'WriteSound' tab without it swapping back. If anyone knows a workaround to this, please let me know.

The final result:


As with the last post, to make this work, you need a .WAV sound file. Check out AT&T Labs and make your own if needed. Make sure to take note of its physical location on your drive.

We're going to be changing the user interface ever so slightly and to do that we'll need to tell Nuke to make some changes. The menu.py file specifies any customization to Nuke's interface, and is usually found in the default user plugins folder. The default locations for this folder are:

Win - 'C:/Documents and Settings/USER/.nuke/
Mac - '$HOME/.nuke/


If you can't find a menu.py file in these folders, go ahead and create your own by saving out of your favorite text editor. To get started, you will need to add the following code to your menu.py file.



import writeSound
writeSound.attachWriteSoundNode()


This tells Nuke to import the writeSound script, and inside of writeSound go ahead and execute the attachWriteSoundNode command.

Next, you will need the following bit of code. Go ahead and copy this into a new file in your text editor.



# Developed by Christian Castaneda
# chris@castanedafx.com
# This should create a custom write node that plays a sound when finished rendering
import nuke

nukeOriginalWriteSoundNode = nuke.createNode

def attachWriteSoundNode():
nuke.createNode = customWriteSoundNode

def customWriteSoundNode(node, knobs = "", inpanel = True):
if node == "Write":
writeNode = nukeOriginalWriteSoundNode( node, knobs, inpanel )
## attach our custom tab
createWriteSoundTab( writeNode )
return writeNode
else:
return nukeOriginalWriteSoundNode( node, knobs, inpanel )

def createWriteSoundTab(node):
#### create knobs
tabKnob = nuke.Tab_Knob('WriteSound')
channelKnob = nuke.Link_Knob('channels_name', 'channels')
fileKnob = nuke.Link_Knob('file_name', 'file')
proxyKnob = nuke.Link_Knob('proxy_name', 'proxy')
divideKnob = nuke.Text_Knob('')
colorKnob = nuke.Link_Knob('colorspace_name', 'colorspace')
preMultKnob = nuke.Link_Knob('premultiplied_name', 'premultiplied')
rawDataKnob = nuke.Link_Knob('raw data name', 'raw data')
viewsKnob = nuke.Link_Knob('views_name', 'views')
typeKnob = nuke.Link_Knob('file type name', 'file type')
orderKnob = nuke.Link_Knob('render_order_name', 'render order')
buttonKnob = nuke.PyScript_Knob('Render With Sound')

#### make links to the Original Write
channelKnob.setLink('channels')
fileKnob.setLink('file')
proxyKnob.setLink('proxy')
colorKnob.setLink('colorspace')
preMultKnob.setLink('premultiplied')
rawDataKnob.setLink('raw')
viewsKnob.setLink('views')
typeKnob.setLink('file_type')
orderKnob.setLink('render_order')

script = """
############ This section by Fredrik Brannbacka #############
##
## Make sure you set the sounds file path
macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/SOUND/FILE'
def playSound():
if nuke.env["MACOS"]:
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python')
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC')
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_(macSound, True)
sound.play()
elif nuke.env["WIN32"]:
import winsound
winsound.PlaySound(winSound, winsound.SND_FILENAME|winsound.SND_ASYNC)

node = nuke.selectedNode()
if node.Class()=='Write':
start,end = nuke.getFramesAndViews('Render Range','%i,%i' % (nuke.root()['first_frame'].value(),nuke.root()['last_frame'].value()))[0].split(',',2)
if nuke.execute(node.name(),int(start),int(end)):
playSound()
"""

buttonKnob.setValue(script)

#### add knobs to node
for k in [tabKnob, channelKnob, fileKnob, proxyKnob, divideKnob, colorKnob, preMultKnob, rawDataKnob, viewsKnob, typeKnob, orderKnob, buttonKnob]:
node.addKnob(k)


Here's an important step to make sure that this works. You need to change the path of the sound file in the code, which should be lines 50/51. Specifically, you are looking for:

## Make sure you set the sounds file path
macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/SOUND/FILE'


Once you're done editing the code, save it out in the same folder as menu.py with the filename of 'writeSound.py'.

Restart Nuke and feel free to enjoy the wonderful bliss that is audible renders. Ahhhhh.



edit post

Render Sound in Nuke View Comments

11:44 AM by , under , , , , ,

Bookmark and Share

Often times I find myself meandering while my comps are rendering. I'm a lost stray soul trekking through the long forgotten desolate land that is my desk. I'm usually planning my next comp, stretching after hours of being desk-bound, wondering if that moldy thing in that corner there is growing and will eventually take over me, and more than likely browsing the internet. But how will I ever know when my renders are complete? Fear not, for we can make Nuke do whatever we please, that's the beauty of scripting. Thanks to Dotcommer, quite a talented classmate, who started this thread at VFXTalk, and thanks to smaragden for coming up with this excellent solution.

First, you will need a .WAV sound file. If you don't have an arsenal of beeps and chimes at your disposal, I recommend going to AT&T text-to-speech labs and create your own personal saying. Mine praises and worships me, and thinks I should run for President of the Galaxy. Once you have it, make sure you take note of its physical location on your drive.

Next, you'll need this snippet of code:

macSound = 'PATH/TO/SOUND/FILE'
winSound = 'PATH/TO/WAVE/FILE'
def playSound():
if nuke.env["MACOS"]:
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python')
sys.path.append('/System/Library/Frameworks/Python.framework/Versions/2.5/Extras/lib/python/PyObjC')
from AppKit import NSSound
sound = NSSound.alloc()
sound.initWithContentsOfFile_byReference_(macSound, True)
sound.play()
elif nuke.env["WIN32"]:
import winsound
winsound.PlaySound(winSound, winsound.SND_FILENAME|winsound.SND_ASYNC)

node = nuke.selectedNode()
if node.Class()=='Write':
start,end = nuke.getFramesAndViews('Render Range','%i,%i' % (nuke.root()['first_frame'].value(),nuke.root()['last_frame'].value()))[0].split(',',2)
if nuke.execute(node.name(),int(start),int(end)):
playSound()


Feel free to use whatever text or script editor you prefer, for this example I'll be using the script editor within Nuke. Go ahead and copy and paste the code into the Script Editor. If you don't see the Script Editor by default, right-click on any one of the content menus to select it.



In the first two lines of code, enter the entire path name of your .WAV file in the specified space. For example, since I'm using Windows, I'll change the second line of code to:


winSound = 'E:/Documents and Settings/Christian/RenderSound.wav'


Since we're going to be using this quite often, let's go ahead and save it somewhere where we can easily access it again. Click on Save Script and save it with a .PY extension:



Now if you ever wanted to use this script again, you could easily load it by pressing the Load Script icon.



Now here's the money part, with your Write Node selected, go ahead and run the script. You can run it by either pressing the icon or the hotkey which is Ctrl-Enter.



If it worked, you should get a little pop-up asking you which frames you would like to render.



As far as I can tell, this doesn't work with single frame renders and executing multiple write nodes in your Nuke script.

I hope this works for you, feel free to let me know if you have any questions.



edit post