snip–><–snip

Coding

Nuke save / restore script editor input

by on Jan.24, 2015, under Nuke, Python

This is something that has bugged me since i started working with nuke, if you doing a little interactive scripting, if you forgot to copy/paste it to your script editor, then it was gone on load / nuke exit.

Her is a snap shot of the code i have in my site menu.py , that is in the NUKE_PATH:

# find the script editor:
import PySide
import PySide.QtGui as QtGui
import os
# get the current qtgui instance
nuke_app = QtGui.QApplication.instance()
# global vars
temp_dir = os.environ['NUKE_TEMP_DIR']
saved_text = '%s/nuke_script_editor.txt' % temp_dir


def get_script_editor():
       '''
              returns the QTextDocument which is the input area for the script editor
       '''
       # get all the widgets
       all_widgets = nuke_app.allWidgets()
       
       script_editor = None
       for w in all_widgets:
           name =  w.objectName()
           # lots of the wigets are not named, ignore them
           if not len(name) == 0:
              if name == 'Script Editor.1':
                   script_editor = w
       
       # get plain text:
       #script_editor.children()[0].toPlainText()
       #get the QTextDocument correctly from the 
       txt_doc = None
       for child in script_editor.children():
           if isinstance(child,PySide.QtGui.QTextDocument):
               txt_doc = child
       return txt_doc

       
def save_script_editor():
       '''
              saves the data from the script edotor to disk
       '''
       script_editor = get_script_editor()
       text = script_editor.toPlainText()
       
       fid = open(saved_text,'w')
       fid.write(text)
       fid.close()
       
       print "script editor saved to: ",saved_text
       

def restore_script_editor():
       '''
              restore the saved script editor data
       '''
       script_editor = get_script_editor()
       
       text = open(saved_text,).read()
       script_editor.setPlainText(text)
       
def checkRootCallbacksSet():
       '''
              setup all the callbacks
       '''
       if nuke.Root().knob('onScriptClose').getValue() == '':
           nuke.addOnScriptClose(save_script_editor, nodeClass='Root')
           
       
       if nuke.Root().knob('onScriptLoad').getValue() == '':
           nuke.addOnScriptLoad(restore_script_editor, nodeClass='Root')
       
       restore_script_editor()

nuke.addOnCreate(checkRootCallbacksSet, nodeClass='Root')

So a quick explanation for what im doing.
Using the QApplication.instance(), im getting the Nuke app, from here i have a convenience method “get_script_editor” that i use to get the QTextDocument that nuke is using to store the script editor data.
I then have 2 methods for saving the data to disk and reading it back from disk.

Then to tie it all together, i use nukes call backs to set it so, when nuke loads for the first time or loads a nuke script, it loads the data from disk. I then use the script close function, this works for either a save / clear or closing the ui, it will write out the script editor data to disk.

I have tested this with nuke 7.0v9, but it should work with all versions of nuke.

Leave a Comment :, , , more...

Capturing Nuke’s stdout and err to a file

by on Jan.20, 2015, under Nuke, Python

Something that has bothered me for quite some time, is not being able to capture Nuke’s STDOUT and STDERR, to a file ot ticket, so that when the Artist come accross an issue and none of the TD’s can help we can save it to a ticket or log for when someone has time.

I was reading through some of the python script in nuke an came accross what i was after at the bottom of:

C:\Program Files\Nuke<version>\plugins\menu.py

So in our site menu.py, i have added the following code that is executed  after the above script is run by nuke:

#################################################################################

# save to an env, so that nuke and any threads that share the environment can find the logger
log_path = os.environ['NUKE_LOGGING_PATH']

import logging
logger = logging.getLogger()
hdlr = logging.FileHandler(log_path)
formatter = logging.Formatter('%(levelname)s %(message)s') #%(asctime)s
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.DEBUG)

# stream redirectors
# pulled from: C:\Program Files\Nuke<version>\plugins\menu.py

class SESysStdIn(SERedirector, nuke.FnPySingleton):
  def readline(self):
    return ""

class SESysStdOut(SERedirector, nuke.FnPySingleton):
  def write(self, out):
    if not len(out.strip()) == 0:
        logger.info(out.strip('\n'))
    nuke.output_redirector(out)

class SESysStdErr(SERedirector, nuke.FnPySingleton):
  def write(self, out):
    if not len(out.strip()) == 0:
        logger.error(out.strip('\n'))
    nuke.stderr_redirector(out)

if nuke.GUI:
  sys.stdin  = SESysStdIn(sys.stdin)
  sys.stdout = SESysStdOut(sys.stdout)
  sys.stderr = SESysStdErr(sys.stderr)
#################################################################################

Then, when nuke ui starts it will create this log and write to it.
The “os.environ[‘NUKE_LOGGING_PATH’]” is because we define a new log for every nuke instance. this is defined when running the init.py in your site config.

Leave a Comment :, more...

Useful links for scripting with Nuke

by on Mar.05, 2012, under Nuke, Python

I have been doing some scripting with Nuke, While the Documentation is great, not being a compositor by trade, knowing the lingo for items in nuke was a pain to get my head around.

So here are some useful links in case i forget what im looking for…

Creating custom panels / widgets and popups in nuke’s python:

http://docs.thefoundry.co.uk/nuke/63/pythondevguide/custom_panels.htm

Visual guide to nuke Knob types:

http://docs.thefoundry.co.uk/nuke/63/ndkdevguide/knobs-and-handles/knobtypes.html

Nuke knob flags (These apply in  python aswell):

http://docs.thefoundry.co.uk/nuke/63/ndkdevguide/knobs-and-handles/knobflags.html

Some useful example scripts i have found:

Pyside webbroswer in nuke:

http://pastebin.com/CC0CJ2Qu

Split multichannel exrs into visible layers in nuke:

http://pastebin.com/G7fFbsXz

Query all the read nodes in a script:

http://pastebin.com/wKFXh3Vf

Path swapping reads and write for a company that has 2 facilities. hmm its hard to guess:

http://pastebin.com/8fK00AMx

Leave a Comment more...

Replying to Shotgun messages on an Android phone.

by on Aug.03, 2011, under Coding, Python

On the project “Them Greeks“, we are using Shotgun for managing the project.

One of the things that annoys me the most is that i cannot reply straight to one of the shotgun emails from a note or Ticket.

To make it even more frustrating i have an android phone and using any of the browsers available i cannot for  the life of me make a reply….

So i decided to see if i could get the shotgun_api3 to run on SL4A python on my android. It worked. Next to write a little wrapper i could use to reply to messages i got in my email.

One of the things I had to do was get the email notes to include the note id, so that i could reply directly to the note via the api.

So to get this to work, you will need to have an android phone with SL4A installed on your android phone.

You will also need Python for Android installed.

Once you have these, you will need to get hold of the shotgun_api and copy it to your phone.
You will need to place the shotgun_api3.py in your sl4a scripts dir, it should live here:

/mnt/sdcard/sl4a/scripts/

So here is my first version of the code, it will need to go into the same directory as above to run.

You can put it into a new directory, but you need to put the shotgun_api3.py in there as well.

#
# setup imports.
import android,os,sys
# setup android
droid = android.Android()
# setup where to find the shotgun api on my phone
# I placed it in my sl4a scripts directory
#
scripts = os.getcwd()
scripts = scripts +'/scripts/'
sys.path.append(scripts)
from shotgun_api3 import Shotgun
#
#
# setup the api script and project im working on.
# this is how sg allows us to communicate with it.
#
SERVER_PATH = "server path"
SCRIPT_NAME = "script name here"
SCRIPT_KEY = "script key here"
#
#
# currently I am the only one using this.
# at a later date ill allow for other users.
userId = 188#kym watts
#
#
def replytoNote(noteId='',noteText='',userId=''):
 #  this is a base function for replying to a note in sg with some android ui
 #  bits added to the mix.
 #
 #
 noteID = droid.dialogGetInput('Value', 'enter noteid:', str(noteId)).result
 print type(noteID), noteID
 if not noteID == None:

  noteId = int(noteID)
  #
  #
  replyText = 'enter reply for note %s:' % (noteId)
  #
  noteText = droid.dialogGetInput('Value', replyText, '').result
  sg = Shotgun(SERVER_PATH,SCRIPT_NAME,SCRIPT_KEY)
  #
  #noteId = 974 #"pipeline - planning" note
  #noteText = 'Did you know if you put your mind to it.\nYou can do awesome things.\n\n'
  dReply = {
   'entity':{'type':'Note','id':noteId},
   'user':{'id':userId,"type":"HumanUser"},
   'content': noteText
   }
  #
  #
  sg.create("Reply",dReply)
  print 'msg sent to note id:%s'%(noteId)
else:
 print 'no note id returned.'

#
#
noteId = 1304
noteText = 'sent from my android phone.'
replytoNote(noteId,'',userId)

So some things that you need to update yourself before you run this for the first time:

SERVER_PATH = "server path"
SCRIPT_NAME = "script name here"
SCRIPT_KEY = "script key here"

These you need to get from your shogun server. It might be good in terms of tracking and debgging to create a api script just for this script.

userId = 188#kym watts

You will also need to know what your user name is , so that your reply’s will come from you and not the api script.

So thats pretty much it.
Some stuff i would like to add in the future is:

Functions to handle tickets and other things to reply to in shotgun.
Functions to deal with queue of reply’s till there is a valid connection with the sg server, this would mean i cn read my mail and do replys on the train and have them send when my phone has service again.

So what happens when you run this?

It will prompt you with 2 text inputs.

The First needs to know what the noteid is. This s the note you want to reply to.

The second is the text that you want to reply with. This text field will accept the enter key to seperate things with a new line.

If you can think of any other useful things this could have give me a shout at:

watts[ d o t]kym[ a t ]gmail[ d o t]com


Leave a Comment :, , , more...

arduino cont.

by on Jan.12, 2011, under Arduino, Coding, Electronics, Uncategorized

Some photos of the prototyping with the lcd and relay replacing the transistor, as well as my workspace:

arduino__cont_001arduino__cont_003arduino__cont_005

arduino__cont_008arduino__cont_010arduino__cont_012

arduino__cont_013

More Photos and code soon.

Leave a Comment :, , , more...

Some cool Arduino related links

by on Nov.17, 2010, under Arduino, Coding

Here are the links to some good pdf’s worth reading:

Arduino programming notebook, by Brian W. Evans. This book is a Reference on how to program with the Arduino language. I really like the way it is written.

Essential C , by By Nick Parlante , from Stanford CS department.  This is a good read for people new to c … It assumes that you have some programming experience.

Fritzing

Leave a Comment :, more...

Jump in to arduino

by on Nov.17, 2010, under Arduino, Coding, Electronics

So i spent the next evening converting the proof of concept over for use with the arduino.

I have added some extra bits:

1) A button for triggering the shutter.

2) A button to Increase the shutter open time.

3) A button to Decrease the shutter open time.

.

.

Parts used:

3 x small push buttons.

4x (insert ohms here) resistors

1x long breadboard.

1x npn transistor.

A ton of hook up wires.

.

The buttons were pretty straight forward to hook up, which was nice. The trigger button is connected to pin 12, the “add time / up” button is connected to pin 7 and the “reduce time / down” button is connected to pin 6.

.

second_go

The code to run the buttons looks like this:

</code>

/*
simple program for setting my canon cameras shutter time.

I do long welding glass exposures and this will come in handy so i
wont need to hold the trigger down for too long.
The arduino will do that for me.

*/

#define SHUTTER 13    // defines the shutter control
#define TRIGGER 12    // defines the trigger button
#define UP      7     // defines the +1 second button
#define DOWN    6     // defines the -1 second button
#define SECOND  1001  // defines how long a second is

int curTime = SECOND; // sets the current time to be one second at the
start of the program
int val = 0;           // this is the trigger button control

int upButton = LOW;
int downButton = LOW;

void setup()
{
 pinMode(SHUTTER,OUTPUT);
 pinMode(TRIGGER,INPUT);
 pinMode(UP,INPUT);
 pinMode(DOWN,INPUT);
 Serial.begin(9600);     // open the serial port at 9600 bps:
                         // so we can see what the arduino is doing
                         //before we attach the lcd screen later.
}
// the loop function
void loop()
{
 // get the vars.
 upButton = digitalRead(UP);
 downButton = digitalRead(DOWN);
 val = digitalRead(TRIGGER);

 if (upButton == HIGH)
 {
  // adds one second on to current time
  curTime = curTime + SECOND;
  Serial.print("up button\n");
  delay(200);
 }
 if (downButton == HIGH)
 {
  // removes one second from current time
  curTime = curTime - SECOND;
  Serial.print("down button\n");
  delay(200);
 }

 if (val == HIGH)
 {

  // takes the photo.
  Serial.print("Shutter will be open for: ");
  Serial.print(curTime);
  Serial.print(" miliseconds\n");
  digitalWrite(SHUTTER,HIGH);
  delay(curTime);
  digitalWrite(SHUTTER,LOW);
  Serial.print("shutter closed\n");
 }
 // delays the loop for a tad
 delay(200);
}

<code>

You’ll see that i have my “SECOND” variable set to 1001. I have been running into issues where the shutter open and close time doesn’t match a correct one second interval…. Which is really strange…

Also because i have no way at the moment to display the information, i’m sending debug prints to the serial, so i can view it on the serial monitor.

second_go

.

I found a really good explanation about the canon 3 pin connect Im interfacing with:

Canon N3 details.

.

To finish this project i have a few more steps to do:

a) Add another button to control the mode the device is in.

b) Get hold of a LCD to allow for real world use……

c) Refine the code,  I’m still learning the api,  so im sure i can clean this up a little and work out where my time is going.

d) Start to plan a durable storage case to house the project in.

second_go

.

Leave a Comment :, , , , , more...

Good Python coding tips / cookbook

by on Apr.14, 2010, under Coding

I love the examples on these pages, but i keep losing the links:

pleac_python

Leave a Comment : more...

Maya startup scripts.

by on Jun.03, 2009, under Coding, Maya

I have wondered for a while about what scripts maya loads when it starts up.
Its always intrigued me and i had some spare time today so i wrote a quite python script to help.

Ta-da!

Here are the scripts maya sources on start up:

/scripts/startup/initialLayout.mel
/scripts/others/setDefaultTemplates.mel
/scripts/startup/initCommandWindow.mel
/scripts/startup/initMainWindow.mel
/scripts/startup/UIComponents.mel
/scripts/startup/initContexts.mel
/scripts/others/flyThroughContextSetup.mel
/scripts/startup/animationStartup.mel
/scripts/startup/initAttributeEditor.mel
/scripts/others/showEditor.mel
/scripts/startup/initToolSettings.mel
/scripts/startup/initChannelsLayers.mel
/scripts/startup/initChannelBox.mel
/scripts/startup/layerEditor.mel
/scripts/startup/initMainPane.mel
/scripts/startup/initPanels.mel
/scripts/startup/initScriptedPanels.mel
/scripts/others/dopeSheetPanel.mel
/scripts/others/clipEditorPanel.mel
/scripts/others/graphEditorPanel.mel
/scripts/others/setEditorPanel.mel
/scripts/others/setEdBookmarkEditor.mel
/scripts/others/rendRelPanel.mel
/scripts/others/componentEditorPanel.mel
/scripts/others/hyperGraphPanel.mel
/scripts/others/hyperShadePanel.mel
/scripts/others/hyperViewer.mel
/scripts/others/visorPanel.mel
/scripts/others/polySelConstraintPanel.mel
/scripts/others/texturePanel.mel
/scripts/others/multiListerPanel.mel
/scripts/others/renderWindowPanel.mel
/scripts/others/ShadingGroupEditorPanel.mel
/scripts/others/dynRelEditorPane.mel
/scripts/others/relationshipEditor.mel
/scripts/others/referenceEditorPanel.mel
/scripts/others/blindDataEditor.mel
/scripts/startup/webBrowserPanel.mel
/scripts/startup/scriptEditorPanel.mel
/scripts/startup/initStatusLine.mel
/scripts/startup/statusLine.mel
/scripts/startup/initTimeSlider.mel
/scripts/others/timeSlider.mel
/scripts/others/initPlaybackRange.mel
/scripts/others/playbackRange.mel
/scripts/startup/initCommandLine.mel
/scripts/startup/initShelf.mel
/scripts/startup/shelf.mel
/scripts/startup/initHelpLine.mel
/scripts/startup/toolbox.mel
/scripts/startup/initAuxiliary.mel
/scripts/startup/initPolygonsUI.mel
/scripts/startup/initNurbsUI.mel
/scripts/startup/initSubdivUI.mel
/scripts/startup/initMinorNodeTypes.mel
/scripts/startup/initMainMenuBar.mel
/scripts/startup/FileMenu.mel
/scripts/startup/EditMenu.mel
/scripts/startup/DisplayMenu.mel
/scripts/startup/ViewMenu.mel
/scripts/startup/HotboxMenus.mel
/scripts/startup/ModEditCurvesMenu.mel
/scripts/paintEffects/CreatorMenu.mel
/scripts/paintEffects/creatorGlobalVars.mel
/scripts/startup/AuxiliaryMenus.mel
/scripts/startup/AuxiliaryGraphicsMenus.mel
/scripts/startup/HelpMenu.mel
/scripts/startup/initManipulators.mel
/scripts/startup/selectionMaskStackInit.mel
/scripts/startup/hotkeySetup.mel
/scripts/startup/namedCommandSetup.mel
// file -f -n;
/scripts/startup/initAfter.mel
/scripts/startup/initHUDScripts.mel

Leave a Comment :, more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!