Skip to content

Instantly share code, notes, and snippets.

@Farfarer
Created August 25, 2017 11:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Farfarer/bf1de739bac2eddaa44d2b0f28d581d4 to your computer and use it in GitHub Desktop.
Save Farfarer/bf1de739bac2eddaa44d2b0f28d581d4 to your computer and use it in GitHub Desktop.
Adds a new command for Modo, clip.newWithSize, which lets you specify explicit width/height of newly created images, rather than the usual square power-of-two.
#!/usr/bin/env python
import os
import lx
import modo
import lxifc
import lxu.select
import lxu.command
def get_ColorSpaces():
savers_name = ['(none)', '(default)']
savers_uname = ['(none)', 'Default']
scn_svc = lx.service.Scene()
itype_scene = scn_svc.ItemTypeLookup (lx.symbol.sITYPE_SCENE)
scene = lx.object.Scene(lxu.select.SceneSelection().current())
scene_item = scene.AnyItemOfType(itype_scene)
sel_svc = lx.service.Selection()
chan_read = lx.object.ChannelRead(scene.Channels(None, sel_svc.GetTime()))
scene_colorspace = chan_read.String(scene_item, scene_item.ChannelLookup(lx.symbol.sICHAN_SCENE_OCIOCONFIG))
if not scene_colorspace or scene_colorspace == '(none)':
return (savers_name, savers_uname)
scene_colorspace_colon = scene_colorspace + ':'
scene_colorspace_colon_len = len(scene_colorspace_colon)
msg_svc = lx.service.Message()
host_svc = lx.service.Host()
for s in xrange(host_svc.NumServers(lx.symbol.a_COLORMAPPING)):
server = host_svc.ServerByIndex(lx.symbol.a_COLORMAPPING, s)
name = server.Name()
if name.startswith(scene_colorspace_colon):
uname = server.UserName()[scene_colorspace_colon_len:]
savers_name.append(name)
savers_uname.append(uname)
for x in xrange(len(savers_uname)):
niceUName = msg_svc.RawText('colorspace', savers_uname[x])
if not (niceUName.startswith('!') and niceUName.endswith('=BUG!')):
savers_uname[x] = niceUName
return (savers_name, savers_uname)
def get_DefaultFormat():
try:
return lx.eval1 ('pref.value application.imageFormatName ?')
except:
return 'PNG16'
def get_ImageSavers():
savers_name = []
savers_uname = []
savers_dostype = []
savers_dostype_lower = []
host_svc = lx.service.Host()
for s in xrange(host_svc.NumServers(lx.symbol.a_SAVER)):
factory = host_svc.ServerByIndex(lx.symbol.a_SAVER, s)
if lx.symbol.a_IMAGE in factory.InfoTag(lx.symbol.sSAV_OUTCLASS):
name = factory.Name()
uname = factory.UserName()
try:
dostype = factory.InfoTag(lx.symbol.sSAV_DOSTYPE)
except:
continue
else:
savers_name.append(name)
savers_uname.append(uname)
savers_dostype.append(dostype)
savers_dostype_lower.append(dostype.lower())
return (savers_name, savers_uname, savers_dostype, savers_dostype_lower)
class OptionPopupFType(lxifc.UIValueHints):
def __init__(self):
self.names = ('Grey', 'RGBA', 'RGB')
self.unames = ('Grey', 'RGBA', 'RGB')
self.count = 3
def uiv_Flags(self):
return lx.symbol.fVALHINT_POPUPS
def uiv_PopCount(self):
return self.count
def uiv_PopUserName(self,index):
return self.unames[index]
def uiv_PopInternalName(self,index):
return self.names[index]
class OptionPopupColorspace(lxifc.UIValueHints):
def __init__(self):
self.names, self.unames = get_ColorSpaces()
self.count = min (len (self.names), len (self.unames))
def uiv_Flags(self):
return lx.symbol.fVALHINT_POPUPS
def uiv_PopCount(self):
return self.count
def uiv_PopUserName(self,index):
return self.unames[index]
def uiv_PopInternalName(self,index):
return self.names[index]
class NewImageWithSize_Cmd(lxu.command.BasicCommand):
def __init__(self):
lxu.command.BasicCommand.__init__(self)
self.dyna_Add('filename', lx.symbol.sTYPE_FILEPATH)
self.basic_SetFlags(0, lx.symbol.fCMDARG_HIDDEN)
self.dyna_Add('width', lx.symbol.sTYPE_INTEGER)
self.dyna_Add('height', lx.symbol.sTYPE_INTEGER)
self.dyna_Add('type', lx.symbol.sTYPE_STRING)
self.basic_SetFlags(3, lx.symbol.fCMDARG_OPTIONAL)
self.dyna_Add('fp', lx.symbol.sTYPE_BOOLEAN)
self.basic_SetFlags(4, lx.symbol.fCMDARG_OPTIONAL)
self.dyna_Add('setColor', lx.symbol.sTYPE_BOOLEAN)
self.basic_SetFlags(5, lx.symbol.fCMDARG_OPTIONAL)
self.dyna_Add('color', lx.symbol.sTYPE_COLOR)
self.basic_SetFlags(6, lx.symbol.fCMDARG_OPTIONAL)
self.dyna_Add('colorspace', lx.symbol.sTYPE_STRING)
self.basic_SetFlags(7, lx.symbol.fCMDARG_OPTIONAL)
def arg_UIHints(self, index, hints):
if index == 1:
hints.Label('Width')
hints.MinInt(1)
elif index == 2:
hints.Label('Height')
hints.MinInt(1)
elif index == 3:
hints.Label('Format')
elif index == 4:
hints.Label('Floating Point')
elif index == 5:
hints.Label('Set Color')
elif index == 6:
hints.Label('Color')
elif index == 7:
hints.Label('Colorspace')
def cmd_ArgEnable (self, index):
if index == 6:
if not self.dyna_Bool (5, False):
lx.throw(lx.symbol.e_CMD_DISABLED)
return True
def arg_UIValueHints(self, index):
if index == 3:
return OptionPopupFType()
elif index == 7:
return OptionPopupColorspace()
def cmd_Interact(self):
if not self.dyna_IsSet (0):
filepath = modo.dialogs.fileSave('image@clip', get_DefaultFormat(), fspec='format', title='New Image...')
if filepath:
self.attr_SetString(0, filepath)
def cmd_DialogInit(self):
if not self.dyna_IsSet (1):
self.attr_SetInt(1, 2048)
if not self.dyna_IsSet (2):
self.attr_SetInt(2, 2048)
if not self.dyna_IsSet (3):
self.attr_SetString(3, 'RGB')
if not self.dyna_IsSet (4):
self.attr_SetInt(4, 0)
if not self.dyna_IsSet (5):
self.attr_SetInt(5, 0)
if not self.dyna_IsSet (6):
self.attr_SetString(6, '0 0 0')
if not self.dyna_IsSet (7):
self.attr_SetString(7, '(default)')
def cmd_Flags(self):
return lx.symbol.fCMD_MODEL | lx.symbol.fCMD_UNDO | lx.symbol.fCMD_MUSTSETARG
def basic_Enable(self, msg):
return True
def cmd_UserName(self):
return 'New Still with Size'
def cmd_Desc(self):
return 'Create a new image clip with specific width and height.'
def cmd_Tooltip(self):
return 'Create a new image clip with specific width and height.'
def basic_ButtonName(self):
return 'New Still with Size'
def basic_Execute(self, msg, flags):
filepath = self.dyna_String(0, None)
if filepath is None:
msg.SetCode(lx.result.CMD_MISSING_ARGS)
return
if not filepath:
msg.SetCode(lx.result.e_FAILED)
msg.SetMessage("clip.new", None, 1)
return
width = max(1, self.dyna_Int(1, 2048))
height = max(1, self.dyna_Int(2, 2048))
ftype = self.dyna_String(3, 'RGB')
fp = self.dyna_Bool(4, False)
setColor = self.dyna_Bool(5, False)
color = self.dyna_String(6, '0 0 0')
colorspace = self.dyna_String(7, '(default)')
savers = get_ImageSavers()
formatDosType = os.path.splitext(filepath)[1].lstrip('.').lower()
if formatDosType in savers[3]:
fileFormat = savers[0][savers[3].index(formatDosType)]
else:
msg.SetCode(lx.result.e_FAILED)
msg.SetMessage("clip.new", None, 1)
return
lx.eval('clip.newStill "%s" type:%s fp:%s setColor:%s color:{%s} format:%s colorspace:%s width:%s height:%s' % (filepath, ftype, fp, setColor, color, fileFormat, colorspace, width, height))
lx.bless(NewImageWithSize_Cmd, 'clip.newWithSize')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment