nukescripts.framecycler

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

# Source Code for Module nukescripts.framecycler

      1  # Copyright (c) 2010 The Foundry Visionmongers Ltd.  All Rights Reserved.
      2  import platform
      3  import sys
      4  import os.path
      5  import re
      6  import thread
      7  import nuke
      8  import subprocess
      9  import nukescripts
     10  import flipbooking
     11
     12  # An example implementation for a flipbook application using framecycler.
     13 -class FramecyclerFlipbook(flipbooking.FlipbookApplication):
     14    # Discover the location of FC on construction
     15 -  def __init__(self):
     16      self._fcPath = ""
     17      try:
     18        self._fcPath = os.environ["FC_PATH"]
     19      except:
     20        try:
     21          self._fcPath = os.path.join(os.environ["FC_HOME"], "bin", "framecycler")
     22        except:
     23          self._fcPath = os.path.join(os.path.dirname(nuke.EXE_PATH), "FrameCycler")
     24          if nuke.env['WIN32']:
     25            self._fcPath = os.path.join(self._fcPath+"Windows", "bin", "framecycler")
     26          elif not nuke.env['WIN32'] and not nuke.env['MACOS']:
     27            self._fcPath = os.path.join(self._fcPath+self.linux_version(), "bin", "framecycler")
     28          else:
     29            self._fcPath = os.path.join(self._fcPath + "OSX", "bin", "FrameCycler")
     30      if nuke.env['WIN32']:
     31          self._fcPath = self._fcPath + ".exe"
     32      self._fcPath = os.path.normpath(self._fcPath)
     33
     34    ##############################################################
     35    # Interface implementation
     36    ##############################################################
     37 -  def name(self):
     38      return "FrameCycler"
     39
     40 -  def path(self):
     41      return self._fcPath
     42
     43 -  def cacheDir(self):
     44      return os.environ["FC_DISK_CACHE"]
     45
     46 -  def run(self, filename, frameRanges, views, options):
     47      (filename, subs) = re.subn("(%[0-9]*)d", "#", filename)
     48      (filename, subs) = re.subn("%V", views[0], filename)
     49      (filename, subs) = re.subn("%v", views[0][0], filename)
     50
     51      os.path.normpath(filename)
     52
     53      args = []
     54      if nuke.env['WIN32']:
     55        args.append( "\"" + self.path() + "\"" )
     56        filename = filename.replace("/", "\\")
     57        filename = "\"" + filename + "\""
     58      else:
     59        args.append( self.path() )
     60
     61      lut = options.get("lut", "")
     62      if lut != "":
     63        lutPath = flipbooking.getLUTPath(self.name(), lut)
     64        if lutPath != "" and os.path.exists(lutPath):
     65          args.append("-calibration")
     66          args.append("\"" + lutPath + "\"")
     67
     68      roi = options.get("roi", None)
     69      if roi != None and not (roi["x"] == 0.0 and roi["y"] == 0.0 and roi["w"] == 0.0 and roi["h"] == 0.0):
     70        args.append("-c"+str(max(0, int(roi["x"]))))
     71        args.append(str(max(0, int(roi["y"]))))
     72        args.append(str(int(roi["w"])))
     73        args.append(str(int(roi["h"])))
     74
     75      scaleW = 100
     76      scaleH = 100
     77
     78      pixelAspect = options.get("pixelAspect", 1)
     79      if pixelAspect != 1:
     80        scaleW *= pixelAspect
     81
     82      if scaleW != 100 or scaleH != 100:
     83        args.append("-r"+str(scaleW)+"%")
     84        args.append(str(scaleH) + "%")
     85
     86      if len(views) > 1:
     87        args.append("-stereo")
     88
     89      # I didn't find any python call that return the maximum argument size for command line.
     90      # I hope that 1000 is enough.
     91      maximun_cmd_args_size = 1000
     92
     93      # audio to be added this may be empty or not
     94      self._audio = ""
     95      audio = options.get("audio", "")
     96      if audio != "":
     97        self._audio = "\"-s" + audio + "\""
     98
     99      for frameRange in frameRanges:
    100        args += self.sequence( frameRange, filename, maximun_cmd_args_size )
    101
    102
    103      nuke.IrToken()
    104      os.spawnv(os.P_NOWAITO, self.path(), args)
    105
    106 -  def capabilities(self):
    107      return {
    108        'proxyScale': False,
    109        'crop': True,
    110        'canPreLaunch': False,
    111        'supportsArbitraryChannels': False,
    112        'maximumViews' : 2,
    113        'fileTypes' : ["exr", "mov", "tif", "tiff", "tga", "cin", "avi", "raw", "bmp", "gif", "jpg", "jpeg", "yuv", "pic", "rla", "dpx", "r3d", "png", "sgi", "rgb"]
    114      }
    115
    116    ##############################################################
    117    # FrameCycler specific functions
    118    ##############################################################
    119
    120 -  def run_app(self, app, in_args):
    121      args = [app]
    122      for a in in_args:
    123        args.append(a)
    124      try:
    125        p = subprocess.Popen(args=args, executable=app, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    126        output, errors = p.communicate()
    127        return output
    128      except:
    129        return ""
    130
    131 -  def linux_version(self):
    132      default_path = "CentOS5"
    133      output = self.run_app("/usr/bin/lsb_release",  ["-a"])
    134      if len(output) == 0:
    135        output = self.run_app("/usr/local/bin/lsb_release", ["-a"])
    136        if len(output) == 0:
    137          output = self.run_app("/bin/lsb_release", ["-a"])
    138          if len(output) == 0:
    139            return default_path
    140      try:
    141        if output.find('CentOS') >= 0:
    142          match = re.search('Release:\s*[\d.]+', output)
    143          if match != None:
    144            substring = match.group(0)
    145            versionMatch = re.search('[\d.]+', substring)
    146            versionString = versionMatch.group(0)
    147            if (float(versionString)) < 5.0:
    148              return "CentOS4.4"
    149      except:
    150        pass
    151      return default_path
    152
    153 -  def _sequenceStr(self, fname, start, end):
    154      return ["Q[", fname, "%d-%d" % (start, end), self._audio, "]Q"]
    155
    156 -  def sequence(self, frange, filename, cmd_args_size):
    157      sequence = []
    158      if frange.increment() == 1:
    159        sequence += self._sequenceStr(filename, frange.first(), frange.last())
    160      else:
    161        for i in xrange(min(frange.frames(), cmd_args_size)):
    162          sequence += self._sequenceStr(filename,
    163              frange.getFrame(i), frange.getFrame(i))
    164      return sequence
    165
    166
    167  # Example call to register a flipbook app.
    168  fc = FramecyclerFlipbook()
    169  flipbooking.register(fc)
    170  # Get the fc install folder so we can register the Nuke specific LUTS, just need
    171  # to remove the last two components from the path.
    172  fcBinPath = os.path.split(fc.path())[0]
    173  fcBasePath = os.path.split(fcBinPath)[0]
    174  flipbooking.registerLUTPath('FrameCycler', 'linear-sRGB', os.path.join(fcBasePath, 'LUTs', 'NukeLinearTosRGB.ilut'))
    175  flipbooking.registerLUTPath('FrameCycler', 'linear-rec709', os.path.join(fcBasePath, 'LUTs', 'NukeLinearToRec709.ilut'))
    176  flipbooking.registerLUTPath('FrameCycler', 'Cineon-sRGB', os.path.join(fcBasePath, 'LUTs', 'NukeCineonTosRGB.cube'))
    177