nukescripts.run_framecycler

Package nukescripts :: Module run_framecycler |
[hide private]
[frames] | no frames]

# Source Code for Module nukescripts.run_framecycler

      1  #
      2  # Copyright (c) 2009 The Foundry Visionmongers Ltd.  All Rights Reserved.
      3  #
      4
      5  # Run framecycler on a Read or Write node. See the flipbook command
      6  # for how we run framecycler on *any* node.
      7
      8  import platform
      9  import sys
     10  import os.path
     11  import re
     12  import thread
     13  import nuke
     14  import subprocess
     15
     16 -def framecycler_stereo_available():
     17    """This function used to detect if we were running on Mac OS Tiger; we no longer support Tiger, so this function always returns true now."""
     18    return True
     19
     20 -def run_app(app, in_args):
     21    args = [app]
     22    for a in in_args:
     23      args.append(a)
     24    try:
     25      p = subprocess.Popen(args=args, executable=app, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
     26      output, errors = p.communicate()
     27      return output
     28    except:
     29      return ""
     30
     31 -def framecycler_linux_version():
     32    default_path = "CentOS5"
     33    output = run_app("/usr/bin/lsb_release",  ["-a"])
     34    if len(output) == 0:
     35      output = run_app("/usr/local/bin/lsb_release", ["-a"])
     36      if len(output) == 0:
     37        output = run_app("/bin/lsb_release", ["-a"])
     38        if len(output) == 0:
     39          return default_path
     40    try:
     41      if output.find('CentOS') >= 0:
     42        match = re.search('Release:\s*[\d.]+', output)
     43        if match != None:
     44          substring = match.group(0)
     45          versionMatch = re.search('[\d.]+', substring)
     46          versionString = versionMatch.group(0)
     47          if (float(versionString)) < 5.0:
     48            return "CentOS4.4"
     49    except:
     50      pass
     51    return default_path
     52
     53  fc_path=""
     54  if fc_path == "":
     55    try:
     56      fc_path = os.environ["FC_PATH"]
     57    except:
     58      try:
     59        fc_path = os.path.join(os.environ["FC_HOME"], "bin", "framecycler")
     60      except:
     61        fc_path = os.path.join(os.path.dirname(nuke.EXE_PATH), "FrameCycler")
     62        fc_suffix = ""
     63        if nuke.env['WIN32']:
     64          fc_path = os.path.join(fc_path+"Windows", "bin", "framecycler")
     65        elif not nuke.env['WIN32'] and not nuke.env['MACOS']:
     66          fc_path = os.path.join(fc_path+framecycler_linux_version(), "bin", "framecycler")
     67        else:
     68          fc_path = os.path.join(fc_path + "OSX", "bin", "FrameCycler")
     69    if nuke.env['WIN32']:
     70        fc_path = fc_path + ".exe"
     71
     72
     73 -def framecycler_sequence(frange, filename, cmd_args_size):
     74    sequence = []
     75    for i in xrange(min(frange.frames(), cmd_args_size)):
     76      sequence.append( "Q[" )
     77      sequence.append( filename )
     78      sequence.append( "%d-%d" % (frange.getFrame(i), frange.getFrame(i)) )
     79      sequence.append( "]Q" )
     80    return sequence
     81
     82 -def framecycler_this(node, start, end, incr, view):
     83    """Run framecycler on a Read or Write node. See the flipbook command
     84    for how we run framecycler on *any* node."""
     85
     86    global fc_path
     87
     88    if not os.access(fc_path, os.X_OK):
     89      raise RuntimeError("Framecycler cannot be executed (%s)." % (fc_path,) )
     90
     91    filename = nuke.filename(node)
     92    if filename is None or filename == "":
     93      raise RuntimeError("Framecycler cannot be executed on '%s', expected to find a filename and there was none." % (node.fullName(),) )
     94
     95    sequence_interval = str(start)+"-"+str(end)
     96    (filename, subs) = re.subn("(%[0-9]+)d", "#", filename)
     97
     98    # if the step beetwen frames is bigger then one
     99    # we have to build the framecycler syntax in a special way
    100    # the idea is to add multiple queue sequence of 1 frame
    101
    102    if subs == 0 or incr > 1:
    103      sequence_interval = ""
    104
    105    (filename, subs) = re.subn("%V", view[0], filename)
    106    (filename, subs) = re.subn("%v", view[0][0], filename)
    107
    108    os.path.normpath(filename)
    109
    110    w = nuke.value(node.name()+".actual_format.width")
    111    h = nuke.value(node.name()+".actual_format.height")
    112    cropa = nuke.value(node.name()+".actual_format.x")
    113    cropb = nuke.value(node.name()+".actual_format.y")
    114    cropc = str(nuke.expression(node.name()+".actual_format.r"+"-"+cropa))
    115    cropd = str(nuke.expression(node.name()+".actual_format.t"+"-"+cropb))
    116    pa = nuke.value(node.name()+".actual_format.pixel_aspect")
    117
    118    args = []
    119    fc_path = os.path.normpath(fc_path)
    120    if nuke.env['WIN32']:
    121      args.append( "\"" + fc_path + "\"" )
    122      filename = filename.replace("/", "\\")
    123      filename = "\"" + filename + "\""
    124    else:
    125      args.append( fc_path )
    126
    127    if incr == 1:
    128      args.append(filename)
    129      args.append(sequence_interval)
    130
    131    if cropa is not None or cropb is not None or cropc != w or cropd != h:
    132      args.append("-c")
    133      args.append(cropa)
    134      args.append(cropb)
    135      args.append(cropc)
    136      args.append(cropd)
    137
    138    resample = ""
    139    if float(pa)>1:
    140      args.append("-r")
    141      args.append("100%")
    142      args.append(str(int(100/float(pa)))+"%")
    143    elif float(pa)<1:
    144      args.append("-r")
    145      args.append(str(int(100/float(pa)))+"%")
    146      args.append("100%")
    147
    148    if len(view) > 1:
    149      args.append("-stereo")
    150
    151    if incr > 1:
    152      # I didn't find any python call that return the maximum argument size for command line.
    153      # I hope that 1000 is enough.
    154      maximun_cmd_args_size = 1000
    155
    156      frange =  nuke.FrameRange(start, end, incr)
    157      sequence = framecycler_sequence( frange, filename, maximun_cmd_args_size )
    158      args += sequence
    159
    160    nuke.IrToken()
    161    os.spawnv(os.P_NOWAITO, fc_path, args)
    162