adding additional integration modules

This commit is contained in:
Jakub Jezek 2019-04-24 12:24:55 +02:00
parent ca92c42cde
commit 6188223567
17 changed files with 3446 additions and 51 deletions

View file

@ -19,27 +19,18 @@ import nuke
from pypeapp import Logger
# #removing logger handler created in avalon_core
# for name, handler in [(handler.get_name(), handler)
# for handler in Logger.logging.root.handlers[:]]:
# if "pype" not in str(name).lower():
# Logger.logging.root.removeHandler(handler)
log = Logger().get_logger(__name__, "nuke")
# log = api.Logger.getLogger(__name__, "nuke")
AVALON_CONFIG = os.getenv("AVALON_CONFIG", "pype")
PARENT_DIR = os.path.dirname(__file__)
PACKAGE_DIR = os.path.dirname(PARENT_DIR)
PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins")
PUBLISH_PATH = os.path.join(PLUGINS_DIR, "nuke", "publish")
LOAD_PATH = os.path.join(PLUGINS_DIR, "nuke", "load")
CREATE_PATH = os.path.join(PLUGINS_DIR, "nuke", "create")
INVENTORY_PATH = os.path.join(PLUGINS_DIR, "nuke", "inventory")
PUBLISH_PATH = os.path.join(PLUGINS_DIR, "nukestudio", "publish")
LOAD_PATH = os.path.join(PLUGINS_DIR, "nukestudio", "load")
CREATE_PATH = os.path.join(PLUGINS_DIR, "nukestudio", "create")
INVENTORY_PATH = os.path.join(PLUGINS_DIR, "nukestudio", "inventory")
self = sys.modules[__name__]
self.nLogger = None
@ -48,42 +39,6 @@ if os.getenv("PYBLISH_GUI", None):
pyblish.register_gui(os.getenv("PYBLISH_GUI", None))
# class NukeHandler(Logger.logging.Handler):
# '''
# Nuke Handler - emits logs into nuke's script editor.
# warning will emit nuke.warning()
# critical and fatal would popup msg dialog to alert of the error.
# '''
#
# def __init__(self):
# api.Logger.logging.Handler.__init__(self)
# self.set_name("Pype_Nuke_Handler")
#
# def emit(self, record):
# # Formated message:
# msg = self.format(record)
#
# if record.levelname.lower() in [
# # "warning",
# "critical",
# "fatal",
# "error"
# ]:
# nuke.message(msg)
#
# '''Adding Nuke Logging Handler'''
# nuke_handler = NukeHandler()
# if nuke_handler.get_name() \
# not in [handler.get_name()
# for handler in Logger.logging.root.handlers[:]]:
# api.Logger.logging.getLogger().addHandler(nuke_handler)
# api.Logger.logging.getLogger().setLevel(Logger.logging.INFO)
#
# if not self.nLogger:
# self.nLogger = Logger
def reload_config():
"""Attempt to reload pipeline at run-time.

View file

@ -1,7 +1,83 @@
import nuke
from avalon.api import Session
from pype.nuke import lib
from pype.nukestudio import lib
import hiero.core
try:
from PySide.QtGui import *
except Exception:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from hiero.ui import findMenuAction
#
def install():
# here is the best place to add menu
from avalon.tools import (
creator,
publish,
workfiles,
cbloader,
cbsceneinventory,
contextmanager,
libraryloader
)
menu_name = os.environ['PYPE_STUDIO_NAME']
# Grab Hiero's MenuBar
M = hiero.ui.menuBar()
# Add a Menu to the MenuBar
file_action = None
try:
check_made_menu = findMenuAction(menu_name)
except:
pass
if not check_made_menu:
menu = M.addMenu(menu_name)
else:
menu = check_made_menu.menu()
actions = [{
'action': QAction(QIcon('icons:Position.png'), 'Set Context', None),
'function': contextmanager.show
},
{
'action': QAction(QIcon('icons:ColorAdd.png'), 'Create...', None),
'function': creator.show
},
{
'action': QAction(QIcon('icons:CopyRectangle.png'), 'Load...', None),
'function': cbloader.show
},
{
'action': QAction(QIcon('icons:Output.png'), 'Publish...', None),
'function': publish.show
},
{
'action': QAction(QIcon('icons:ModifyMetaData.png'), 'Manage...', None),
'function': cbsceneinventory.show
},
{
'action': QAction(QIcon('icons:ColorAdd.png'), 'Library...', None),
'function': libraryloader.show
}]
# Create menu items
for a in actions:
# create action
for k in a.keys():
if 'action' in k:
action = a[k]
elif 'function' in k:
action.triggered.connect(a[k])
else:
pass
# add action to menu
menu.addAction(action)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,140 @@
# This action adds itself to the Spreadsheet View context menu allowing the contents of the Spreadsheet be exported as a CSV file.
# Usage: Right-click in Spreadsheet > "Export as .CSV"
# Note: This only prints the text data that is visible in the active Spreadsheet View.
# If you've filtered text, only the visible text will be printed to the CSV file
# Usage: Copy to ~/.hiero/Python/StartupUI
import hiero.core.events
import hiero.ui
import os, csv
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
### Magic Widget Finding Methods - This stuff crawls all the PySide widgets, looking for an answer
def findWidget(w):
global foundryWidgets
if 'Foundry' in w.metaObject().className():
foundryWidgets += [w]
for c in w.children():
findWidget(c)
return foundryWidgets
def getFoundryWidgetsWithClassName(filter=None):
global foundryWidgets
foundryWidgets = []
widgets = []
app = QApplication.instance()
for w in app.topLevelWidgets():
findWidget(w)
filteredWidgets = foundryWidgets
if filter:
filteredWidgets = []
for widget in foundryWidgets:
if filter in widget.metaObject().className():
filteredWidgets += [widget]
return filteredWidgets
# When right click, get the Sequence Name
def activeSpreadsheetTreeView():
"""
Does some PySide widget Magic to detect the Active Spreadsheet TreeView.
"""
spreadsheetViews = getFoundryWidgetsWithClassName(
filter='SpreadsheetTreeView')
for spreadSheet in spreadsheetViews:
if spreadSheet.hasFocus():
activeSpreadSheet = spreadSheet
return activeSpreadSheet
return None
#### Adds "Export .CSV" action to the Spreadsheet Context menu ####
class SpreadsheetExportCSVAction(QAction):
def __init__(self):
QAction.__init__(self, "Export as .CSV", None)
self.triggered.connect(self.exportCSVFromActiveSpreadsheetView)
hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet",
self.eventHandler)
self.setIcon(QIcon("icons:FBGridView.png"))
def eventHandler(self, event):
# Insert the action to the Export CSV menu
event.menu.addAction(self)
#### The guts!.. Writes a CSV file from a Sequence Object ####
def exportCSVFromActiveSpreadsheetView(self):
# Get the active QTreeView from the active Spreadsheet
spreadsheetTreeView = activeSpreadsheetTreeView()
if not spreadsheetTreeView:
return 'Unable to detect the active TreeView.'
seq = hiero.ui.activeView().sequence()
if not seq:
print 'Unable to detect the active Sequence from the activeView.'
return
# The data model of the QTreeView
model = spreadsheetTreeView.model()
csvSavePath = os.path.join(QDir.homePath(), 'Desktop',
seq.name() + '.csv')
savePath, filter = QFileDialog.getSaveFileName(
None,
caption="Export Spreadsheet to .CSV as...",
dir=csvSavePath,
filter="*.csv")
print 'Saving To: ' + str(savePath)
# Saving was cancelled...
if len(savePath) == 0:
return
# Get the Visible Header Columns from the QTreeView
#csvHeader = ['Event', 'Status', 'Shot Name', 'Reel', 'Track', 'Speed', 'Src In', 'Src Out','Src Duration', 'Dst In', 'Dst Out', 'Dst Duration', 'Clip', 'Clip Media']
# Get a CSV writer object
f = open(savePath, 'w')
csvWriter = csv.writer(
f, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
# This is a list of the Column titles
csvHeader = []
for col in range(0, model.columnCount()):
if not spreadsheetTreeView.isColumnHidden(col):
csvHeader += [model.headerData(col, Qt.Horizontal)]
# Write the Header row to the CSV file
csvWriter.writerow(csvHeader)
# Go through each row/column and print
for row in range(model.rowCount()):
row_data = []
for col in range(model.columnCount()):
if not spreadsheetTreeView.isColumnHidden(col):
row_data.append(
model.index(row, col, QModelIndex()).data(
Qt.DisplayRole))
# Write row to CSV file...
csvWriter.writerow(row_data)
f.close()
# Conveniently show the CSV file in the native file browser...
QDesktopServices.openUrl(
QUrl('file:///%s' % (os.path.dirname(savePath))))
# Add the action...
csvActions = SpreadsheetExportCSVAction()

View file

@ -0,0 +1,164 @@
# setFrameRate - adds a Right-click menu to the Project Bin view, allowing multiple BinItems (Clips/Sequences) to have their frame rates set.
# Install in: ~/.hiero/Python/StartupUI
# Requires 1.5v1 or later
import hiero.core
import hiero.ui
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtCore import *
from PySide2.QtWidgets import *
# Dialog for setting a Custom frame rate.
class SetFrameRateDialog(QDialog):
def __init__(self,itemSelection=None,parent=None):
super(SetFrameRateDialog, self).__init__(parent)
self.setWindowTitle("Set Custom Frame Rate")
self.setSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed )
layout = QFormLayout()
self._itemSelection = itemSelection
self._frameRateField = QLineEdit()
self._frameRateField.setToolTip('Enter custom frame rate here.')
self._frameRateField.setValidator(QDoubleValidator(1, 99, 3, self))
self._frameRateField.textChanged.connect(self._textChanged)
layout.addRow("Enter fps: ",self._frameRateField)
# Standard buttons for Add/Cancel
self._buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self._buttonbox.accepted.connect(self.accept)
self._buttonbox.rejected.connect(self.reject)
self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)
layout.addRow("",self._buttonbox)
self.setLayout(layout)
def _updateOkButtonState(self):
# Cancel is always an option but only enable Ok if there is some text.
currentFramerate = float(self.currentFramerateString())
enableOk = False
enableOk = ((currentFramerate > 0.0) and (currentFramerate <= 250.0))
print 'enabledOk',enableOk
self._buttonbox.button(QDialogButtonBox.Ok).setEnabled(enableOk)
def _textChanged(self, newText):
self._updateOkButtonState()
# Returns the current frame rate as a string
def currentFramerateString(self):
return str(self._frameRateField.text())
# Presents the Dialog and sets the Frame rate from a selection
def showDialogAndSetFrameRateFromSelection(self):
if self._itemSelection is not None:
if self.exec_():
# For the Undo loop...
# Construct an TimeBase object for setting the Frame Rate (fps)
fps = hiero.core.TimeBase().fromString(self.currentFramerateString())
# Set the frame rate for the selected BinItmes
for item in self._itemSelection:
item.setFramerate(fps)
return
# This is just a convenience method for returning QActions with a title, triggered method and icon.
def makeAction(title, method, icon = None):
action = QAction(title,None)
action.setIcon(QIcon(icon))
# We do this magic, so that the title string from the action is used to set the frame rate!
def methodWrapper():
method(title)
action.triggered.connect( methodWrapper )
return action
# Menu which adds a Set Frame Rate Menu to Project Bin view
class SetFrameRateMenu:
def __init__(self):
self._frameRateMenu = None
self._frameRatesDialog = None
# ant: Could use hiero.core.defaultFrameRates() here but messes up with string matching because we seem to mix decimal points
self.frameRates = ['8','12','12.50','15','23.98','24','25','29.97','30','48','50','59.94','60']
hiero.core.events.registerInterest("kShowContextMenu/kBin", self.binViewEventHandler)
self.menuActions = []
def createFrameRateMenus(self,selection):
selectedClipFPS = [str(bi.activeItem().framerate()) for bi in selection if (isinstance(bi,hiero.core.BinItem) and hasattr(bi,'activeItem'))]
selectedClipFPS = hiero.core.util.uniquify(selectedClipFPS)
sameFrameRate = len(selectedClipFPS)==1
self.menuActions = []
for fps in self.frameRates:
if fps in selectedClipFPS:
if sameFrameRate:
self.menuActions+=[makeAction(fps,self.setFrameRateFromMenuSelection, icon="icons:Ticked.png")]
else:
self.menuActions+=[makeAction(fps,self.setFrameRateFromMenuSelection, icon="icons:remove active.png")]
else:
self.menuActions+=[makeAction(fps,self.setFrameRateFromMenuSelection, icon=None)]
# Now add Custom... menu
self.menuActions+=[makeAction('Custom...',self.setFrameRateFromMenuSelection, icon=None)]
frameRateMenu = QMenu("Set Frame Rate")
for a in self.menuActions:
frameRateMenu.addAction(a)
return frameRateMenu
def setFrameRateFromMenuSelection(self, menuSelectionFPS):
selectedBinItems = [bi.activeItem() for bi in self._selection if (isinstance(bi,hiero.core.BinItem) and hasattr(bi,'activeItem'))]
currentProject = selectedBinItems[0].project()
with currentProject.beginUndo("Set Frame Rate"):
if menuSelectionFPS == 'Custom...':
self._frameRatesDialog = SetFrameRateDialog(itemSelection = selectedBinItems )
self._frameRatesDialog.showDialogAndSetFrameRateFromSelection()
else:
for b in selectedBinItems:
b.setFramerate(hiero.core.TimeBase().fromString(menuSelectionFPS))
return
# This handles events from the Project Bin View
def binViewEventHandler(self,event):
if not hasattr(event.sender, 'selection'):
# Something has gone wrong, we should only be here if raised
# by the Bin view which gives a selection.
return
# Reset the selection to None...
self._selection = None
s = event.sender.selection()
# Return if there's no Selection. We won't add the Menu.
if s == None:
return
# Filter the selection to BinItems
self._selection = [item for item in s if isinstance(item, hiero.core.BinItem)]
if len(self._selection)==0:
return
# Creating the menu based on items selected, to highlight which frame rates are contained
self._frameRateMenu = self.createFrameRateMenus(self._selection)
# Insert the Set Frame Rate Button before the Set Media Colour Transform Action
for action in event.menu.actions():
if str(action.text()) == "Set Media Colour Transform":
event.menu.insertMenu(action, self._frameRateMenu)
break
# Instantiate the Menu to get it to register itself.
SetFrameRateMenu = SetFrameRateMenu()

View file

@ -0,0 +1,352 @@
# version_up_everywhere.py
# Adds action to enable a Clip/Shot to be Min/Max/Next/Prev versioned in all shots used in a Project.
#
# Usage:
# 1) Copy file to <HIERO_PLUGIN_PATH>/Python/Startup
# 2) Right-click on Clip(s) or Bins containing Clips in in the Bin View, or on Shots in the Timeline/Spreadsheet
# 3) Set Version for all Shots > OPTION to update the version in all shots where the Clip is used in the Project.
import hiero.core
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
def whereAmI(self, searchType='TrackItem'):
"""returns a list of TrackItem or Sequnece objects in the Project which contain this Clip.
By default this will return a list of TrackItems where the Clip is used in its project.
You can also return a list of Sequences by specifying the searchType to be 'Sequence'.
Should consider putting this into hiero.core.Clip by default?
Example usage:
shotsForClip = clip.whereAmI('TrackItem')
sequencesForClip = clip.whereAmI('Sequence')
"""
proj = self.project()
if ('TrackItem' not in searchType) and ('Sequence' not in searchType):
print "searchType argument must be 'TrackItem' or 'Sequence'"
return None
# If user specifies a TrackItem, then it will return
searches = hiero.core.findItemsInProject(proj, searchType)
if len(searches) == 0:
print 'Unable to find %s in any items of type: %s' % (str(self),
str(searchType))
return None
# Case 1: Looking for Shots (trackItems)
clipUsedIn = []
if isinstance(searches[0], hiero.core.TrackItem):
for shot in searches:
# We have to wrap this in a try/except because it's possible through the Python API for a Shot to exist without a Clip in the Bin
try:
# For versioning to work, we must look to the BinItem that a Clip is wrapped in.
if shot.source().binItem() == self.binItem():
clipUsedIn.append(shot)
# If we throw an exception here its because the Shot did not have a Source Clip in the Bin.
except RuntimeError:
hiero.core.log.info(
'Unable to find Parent Clip BinItem for Shot: %s, Source:%s'
% (shot, shot.source()))
pass
# Case 1: Looking for Shots (trackItems)
elif isinstance(searches[0], hiero.core.Sequence):
for seq in searches:
# Iterate tracks > shots...
tracks = seq.items()
for track in tracks:
shots = track.items()
for shot in shots:
if shot.source().binItem() == self.binItem():
clipUsedIn.append(seq)
return clipUsedIn
# Add whereAmI method to Clip object
hiero.core.Clip.whereAmI = whereAmI
#### MAIN VERSION EVERYWHERE GUBBINS #####
class VersionAllMenu(object):
# These are a set of action names we can use for operating on multiple Clip/TrackItems
eMaxVersion = "Max Version"
eMinVersion = "Min Version"
eNextVersion = "Next Version"
ePreviousVersion = "Previous Version"
# This is the title used for the Version Menu title. It's long isn't it?
actionTitle = "Set Version for all Shots"
def __init__(self):
self._versionEverywhereMenu = None
self._versionActions = []
hiero.core.events.registerInterest("kShowContextMenu/kBin",
self.binViewEventHandler)
hiero.core.events.registerInterest("kShowContextMenu/kTimeline",
self.binViewEventHandler)
hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet",
self.binViewEventHandler)
def showVersionUpdateReportFromShotManifest(self, sequenceShotManifest):
"""This just displays an info Message box, based on a Sequence[Shot] manifest dictionary"""
# Now present an info dialog, explaining where shots were updated
updateReportString = "The following Versions were updated:\n"
for seq in sequenceShotManifest.keys():
updateReportString += "%s:\n Shots:\n" % (seq.name())
for shot in sequenceShotManifest[seq]:
updateReportString += ' %s\n (New Version: %s)\n' % (
shot.name(), shot.currentVersion().name())
updateReportString += '\n'
infoBox = QMessageBox(hiero.ui.mainWindow())
infoBox.setIcon(QMessageBox.Information)
if len(sequenceShotManifest) <= 0:
infoBox.setText("No Shot Versions were updated")
infoBox.setInformativeText(
"Clip could not be found in any Shots in this Project")
else:
infoBox.setText(
"Versions were updated in %i Sequences of this Project." %
(len(sequenceShotManifest)))
infoBox.setInformativeText("Show Details for more info.")
infoBox.setDetailedText(updateReportString)
infoBox.exec_()
def makeVersionActionForSingleClip(self, version):
"""This is used to populate the QAction list of Versions when a single Clip is selected in the BinView.
It also triggers the Version Update action based on the version passed to it.
(Not sure if this is good design practice, but it's compact!)"""
action = QAction(version.name(), None)
action.setData(lambda: version)
def updateAllTrackItems():
currentClip = version.item()
trackItems = currentClip.whereAmI()
if not trackItems:
return
proj = currentClip.project()
# A Sequence-Shot manifest dictionary
sequenceShotManifest = {}
# Make this all undo-able in a single Group undo
with proj.beginUndo(
"Update All Versions for %s" % currentClip.name()):
for shot in trackItems:
seq = shot.parentSequence()
if seq not in sequenceShotManifest.keys():
sequenceShotManifest[seq] = [shot]
else:
sequenceShotManifest[seq] += [shot]
shot.setCurrentVersion(version)
# We also should update the current Version of the selected Clip for completeness...
currentClip.binItem().setActiveVersion(version)
# Now disaplay a Dialog which informs the user of where and what was changed
self.showVersionUpdateReportFromShotManifest(sequenceShotManifest)
action.triggered.connect(updateAllTrackItems)
return action
# This is just a convenience method for returning QActions with a title, triggered method and icon.
def makeAction(self, title, method, icon=None):
action = QAction(title, None)
action.setIcon(QIcon(icon))
# We do this magic, so that the title string from the action is used to trigger the version change
def methodWrapper():
method(title)
action.triggered.connect(methodWrapper)
return action
def clipSelectionFromView(self, view):
"""Helper method to return a list of Clips in the Active View"""
selection = hiero.ui.activeView().selection()
if len(selection) == 0:
return None
if isinstance(view, hiero.ui.BinView):
# We could have a mixture of Bins and Clips selected, so sort of the Clips and Clips inside Bins
clipItems = [
item.activeItem() for item in selection
if hasattr(item, "activeItem")
and isinstance(item.activeItem(), hiero.core.Clip)
]
# We'll also append Bins here, and see if can find Clips inside
bins = [
item for item in selection if isinstance(item, hiero.core.Bin)
]
# We search inside of a Bin for a Clip which is not already in clipBinItems
if len(bins) > 0:
# Grab the Clips inside of a Bin and append them to a list
for bin in bins:
clips = hiero.core.findItemsInBin(bin, 'Clip')
for clip in clips:
if clip not in clipItems:
clipItems.append(clip)
elif isinstance(view,
(hiero.ui.TimelineEditor, hiero.ui.SpreadsheetView)):
# Here, we have shots. To get to the Clip froma TrackItem, just call source()
clipItems = [
item.source() for item in selection if hasattr(item, "source")
and isinstance(item, hiero.core.TrackItem)
]
return clipItems
# This generates the Version Up Everywhere menu
def createVersionEveryWhereMenuForView(self, view):
versionEverywhereMenu = QMenu(self.actionTitle)
self._versionActions = []
# We look to the activeView for a selection of Clips
clips = self.clipSelectionFromView(view)
# And bail if nothing is found
if len(clips) == 0:
return versionEverywhereMenu
# Now, if we have just one Clip selected, we'll form a special menu, which lists all versions
if len(clips) == 1:
# Get a reversed list of Versions, so that bigger ones appear at top
versions = list(reversed(clips[0].binItem().items()))
for version in versions:
self._versionActions += [
self.makeVersionActionForSingleClip(version)
]
elif len(clips) > 1:
# We will add Max/Min/Prev/Next options, which can be called on a TrackItem, without the need for a Version object
self._versionActions += [
self.makeAction(
self.eMaxVersion,
self.setTrackItemVersionForClipSelection,
icon=None)
]
self._versionActions += [
self.makeAction(
self.eMinVersion,
self.setTrackItemVersionForClipSelection,
icon=None)
]
self._versionActions += [
self.makeAction(
self.eNextVersion,
self.setTrackItemVersionForClipSelection,
icon=None)
]
self._versionActions += [
self.makeAction(
self.ePreviousVersion,
self.setTrackItemVersionForClipSelection,
icon=None)
]
for act in self._versionActions:
versionEverywhereMenu.addAction(act)
return versionEverywhereMenu
def setTrackItemVersionForClipSelection(self, versionOption):
view = hiero.ui.activeView()
if not view:
return
clipSelection = self.clipSelectionFromView(view)
if len(clipSelection) == 0:
return
proj = clipSelection[0].project()
# Create a Sequence-Shot Manifest, to report to users where a Shot was updated
sequenceShotManifest = {}
with proj.beginUndo("Update multiple Versions"):
for clip in clipSelection:
# Look to see if it exists in a TrackItem somewhere...
shotUsage = clip.whereAmI('TrackItem')
# Next, depending on the versionOption, make the appropriate update
# There's probably a more neat/compact way of doing this...
for shot in shotUsage:
# This step is done for reporting reasons
seq = shot.parentSequence()
if seq not in sequenceShotManifest.keys():
sequenceShotManifest[seq] = [shot]
else:
sequenceShotManifest[seq] += [shot]
if versionOption == self.eMaxVersion:
shot.maxVersion()
elif versionOption == self.eMinVersion:
shot.minVersion()
elif versionOption == self.eNextVersion:
shot.nextVersion()
elif versionOption == self.ePreviousVersion:
shot.prevVersion()
# Finally, for completeness, set the Max/Min version of the Clip too (if chosen)
# Note: It doesn't make sense to do Next/Prev on a Clip here because next/prev means different things for different Shots
if versionOption == self.eMaxVersion:
clip.binItem().maxVersion()
elif versionOption == self.eMinVersion:
clip.binItem().minVersion()
# Now disaplay a Dialog which informs the user of where and what was changed
self.showVersionUpdateReportFromShotManifest(sequenceShotManifest)
# This handles events from the Project Bin View
def binViewEventHandler(self, event):
if not hasattr(event.sender, 'selection'):
# Something has gone wrong, we should only be here if raised
# by the Bin view which gives a selection.
return
selection = event.sender.selection()
# Return if there's no Selection. We won't add the Localise Menu.
if selection == None:
return
view = hiero.ui.activeView()
# Only add the Menu if Bins or Sequences are selected (this ensures menu isn't added in the Tags Pane)
if len(selection) > 0:
self._versionEverywhereMenu = self.createVersionEveryWhereMenuForView(
view)
hiero.ui.insertMenuAction(
self._versionEverywhereMenu.menuAction(),
event.menu,
after="foundry.menu.version")
return
# Instantiate the Menu to get it to register itself.
VersionAllMenu = VersionAllMenu()

View file

@ -0,0 +1,844 @@
# PimpMySpreadsheet 1.0, Antony Nasce, 23/05/13.
# Adds custom spreadsheet columns and right-click menu for setting the Shot Status, and Artist Shot Assignement.
# gStatusTags is a global dictionary of key(status)-value(icon) pairs, which can be overridden with custom icons if required
# Requires Hiero 1.7v2 or later.
# Install Instructions: Copy to ~/.hiero/Python/StartupUI
import hiero.core
import hiero.ui
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
# Set to True, if you wat 'Set Status' right-click menu, False if not
kAddStatusMenu = True
# Set to True, if you wat 'Assign Artist' right-click menu, False if not
kAssignArtistMenu = True
# Global list of Artist Name Dictionaries
# Note: Override this to add different names, icons, department, IDs.
gArtistList = [{
'artistName': 'John Smith',
'artistIcon': 'icons:TagActor.png',
'artistDepartment': '3D',
'artistID': 0
}, {
'artistName': 'Savlvador Dali',
'artistIcon': 'icons:TagActor.png',
'artistDepartment': 'Roto',
'artistID': 1
}, {
'artistName': 'Leonardo Da Vinci',
'artistIcon': 'icons:TagActor.png',
'artistDepartment': 'Paint',
'artistID': 2
}, {
'artistName': 'Claude Monet',
'artistIcon': 'icons:TagActor.png',
'artistDepartment': 'Comp',
'artistID': 3
}, {
'artistName': 'Pablo Picasso',
'artistIcon': 'icons:TagActor.png',
'artistDepartment': 'Animation',
'artistID': 4
}]
# Global Dictionary of Status Tags.
# Note: This can be overwritten if you want to add a new status cellType or custom icon
# Override the gStatusTags dictionary by adding your own 'Status':'Icon.png' key-value pairs.
# Add new custom keys like so: gStatusTags['For Client'] = 'forClient.png'
gStatusTags = {
'Approved': 'icons:status/TagApproved.png',
'Unapproved': 'icons:status/TagUnapproved.png',
'Ready To Start': 'icons:status/TagReadyToStart.png',
'Blocked': 'icons:status/TagBlocked.png',
'On Hold': 'icons:status/TagOnHold.png',
'In Progress': 'icons:status/TagInProgress.png',
'Awaiting Approval': 'icons:status/TagAwaitingApproval.png',
'Omitted': 'icons:status/TagOmitted.png',
'Final': 'icons:status/TagFinal.png'
}
# The Custom Spreadsheet Columns
class CustomSpreadsheetColumns(QObject):
"""
A class defining custom columns for Hiero's spreadsheet view. This has a similar, but
slightly simplified, interface to the QAbstractItemModel and QItemDelegate classes.
"""
global gStatusTags
global gArtistList
# Ideally, we'd set this list on a Per Item basis, but this is expensive for a large mixed selection
standardColourSpaces = [
'linear', 'sRGB', 'rec709', 'Cineon', 'Gamma1.8', 'Gamma2.2',
'Panalog', 'REDLog', 'ViperLog'
]
arriColourSpaces = [
'Video - Rec709', 'LogC - Camera Native', 'Video - P3', 'ACES',
'LogC - Film', 'LogC - Wide Gamut'
]
r3dColourSpaces = [
'Linear', 'Rec709', 'REDspace', 'REDlog', 'PDlog685', 'PDlog985',
'CustomPDlog', 'REDgamma', 'SRGB', 'REDlogFilm', 'REDgamma2',
'REDgamma3'
]
gColourSpaces = standardColourSpaces + arriColourSpaces + r3dColourSpaces
currentView = hiero.ui.activeView()
# This is the list of Columns available
gCustomColumnList = [
{
'name': 'Tags',
'cellType': 'readonly'
},
{
'name': 'Colourspace',
'cellType': 'dropdown'
},
{
'name': 'Notes',
'cellType': 'readonly'
},
{
'name': 'FileType',
'cellType': 'readonly'
},
{
'name': 'Shot Status',
'cellType': 'dropdown'
},
{
'name': 'Thumbnail',
'cellType': 'readonly'
},
{
'name': 'MediaType',
'cellType': 'readonly'
},
{
'name': 'Width',
'cellType': 'readonly'
},
{
'name': 'Height',
'cellType': 'readonly'
},
{
'name': 'Pixel Aspect',
'cellType': 'readonly'
},
{
'name': 'Artist',
'cellType': 'dropdown'
},
{
'name': 'Department',
'cellType': 'readonly'
},
]
def numColumns(self):
"""
Return the number of custom columns in the spreadsheet view
"""
return len(self.gCustomColumnList)
def columnName(self, column):
"""
Return the name of a custom column
"""
return self.gCustomColumnList[column]['name']
def getTagsString(self, item):
"""
Convenience method for returning all the Notes in a Tag as a string
"""
tagNames = []
tags = item.tags()
for tag in tags:
tagNames += [tag.name()]
tagNameString = ','.join(tagNames)
return tagNameString
def getNotes(self, item):
"""
Convenience method for returning all the Notes in a Tag as a string
"""
notes = ''
tags = item.tags()
for tag in tags:
note = tag.note()
if len(note) > 0:
notes += tag.note() + ', '
return notes[:-2]
def getData(self, row, column, item):
"""
Return the data in a cell
"""
currentColumn = self.gCustomColumnList[column]
if currentColumn['name'] == 'Tags':
return self.getTagsString(item)
if currentColumn['name'] == 'Colourspace':
try:
colTransform = item.sourceMediaColourTransform()
except:
colTransform = '--'
return colTransform
if currentColumn['name'] == 'Notes':
try:
note = self.getNotes(item)
except:
note = ''
return note
if currentColumn['name'] == 'FileType':
fileType = '--'
M = item.source().mediaSource().metadata()
if M.hasKey('foundry.source.type'):
fileType = M.value('foundry.source.type')
elif M.hasKey('media.input.filereader'):
fileType = M.value('media.input.filereader')
return fileType
if currentColumn['name'] == 'Shot Status':
status = item.status()
if not status:
status = "--"
return str(status)
if currentColumn['name'] == 'MediaType':
M = item.mediaType()
return str(M).split('MediaType')[-1].replace('.k', '')
if currentColumn['name'] == 'Thumbnail':
return str(item.eventNumber())
if currentColumn['name'] == 'Width':
return str(item.source().format().width())
if currentColumn['name'] == 'Height':
return str(item.source().format().height())
if currentColumn['name'] == 'Pixel Aspect':
return str(item.source().format().pixelAspect())
if currentColumn['name'] == 'Artist':
if item.artist():
name = item.artist()['artistName']
return name
else:
return '--'
if currentColumn['name'] == 'Department':
if item.artist():
dep = item.artist()['artistDepartment']
return dep
else:
return '--'
return ""
def setData(self, row, column, item, data):
"""
Set the data in a cell - unused in this example
"""
return None
def getTooltip(self, row, column, item):
"""
Return the tooltip for a cell
"""
currentColumn = self.gCustomColumnList[column]
if currentColumn['name'] == 'Tags':
return str([item.name() for item in item.tags()])
if currentColumn['name'] == 'Notes':
return str(self.getNotes(item))
return ""
def getFont(self, row, column, item):
"""
Return the tooltip for a cell
"""
return None
def getBackground(self, row, column, item):
"""
Return the background colour for a cell
"""
if not item.source().mediaSource().isMediaPresent():
return QColor(80, 20, 20)
return None
def getForeground(self, row, column, item):
"""
Return the text colour for a cell
"""
#if column == 1:
# return QColor(255, 64, 64)
return None
def getIcon(self, row, column, item):
"""
Return the icon for a cell
"""
currentColumn = self.gCustomColumnList[column]
if currentColumn['name'] == 'Colourspace':
return QIcon("icons:LUT.png")
if currentColumn['name'] == 'Shot Status':
status = item.status()
if status:
return QIcon(gStatusTags[status])
if currentColumn['name'] == 'MediaType':
mediaType = item.mediaType()
if mediaType == hiero.core.TrackItem.kVideo:
return QIcon("icons:VideoOnly.png")
elif mediaType == hiero.core.TrackItem.kAudio:
return QIcon("icons:AudioOnly.png")
if currentColumn['name'] == 'Artist':
try:
return QIcon(item.artist()['artistIcon'])
except:
return None
return None
def getSizeHint(self, row, column, item):
"""
Return the size hint for a cell
"""
currentColumnName = self.gCustomColumnList[column]['name']
if currentColumnName == 'Thumbnail':
return QSize(90, 50)
return QSize(50, 50)
def paintCell(self, row, column, item, painter, option):
"""
Paint a custom cell. Return True if the cell was painted, or False to continue
with the default cell painting.
"""
currentColumn = self.gCustomColumnList[column]
if currentColumn['name'] == 'Tags':
if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.highlight())
iconSize = 20
r = QRect(option.rect.x(),
option.rect.y() + (option.rect.height() - iconSize) / 2,
iconSize, iconSize)
tags = item.tags()
if len(tags) > 0:
painter.save()
painter.setClipRect(option.rect)
for tag in item.tags():
M = tag.metadata()
if not (M.hasKey('tag.status')
or M.hasKey('tag.artistID')):
QIcon(tag.icon()).paint(painter, r, Qt.AlignLeft)
r.translate(r.width() + 2, 0)
painter.restore()
return True
if currentColumn['name'] == 'Thumbnail':
imageView = None
pen = QPen()
r = QRect(option.rect.x() + 2, (option.rect.y() +
(option.rect.height() - 46) / 2),
85, 46)
if not item.source().mediaSource().isMediaPresent():
imageView = QImage("icons:Offline.png")
pen.setColor(QColor(Qt.red))
if item.mediaType() == hiero.core.TrackItem.MediaType.kAudio:
imageView = QImage("icons:AudioOnly.png")
#pen.setColor(QColor(Qt.green))
painter.fillRect(r, QColor(45, 59, 45))
if option.state & QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.highlight())
tags = item.tags()
painter.save()
painter.setClipRect(option.rect)
if not imageView:
try:
imageView = item.thumbnail(item.sourceIn())
pen.setColor(QColor(20, 20, 20))
# If we're here, we probably have a TC error, no thumbnail, so get it from the source Clip...
except:
pen.setColor(QColor(Qt.red))
if not imageView:
try:
imageView = item.source().thumbnail()
pen.setColor(QColor(Qt.yellow))
except:
imageView = QImage("icons:Offline.png")
pen.setColor(QColor(Qt.red))
QIcon(QPixmap.fromImage(imageView)).paint(painter, r,
Qt.AlignCenter)
painter.setPen(pen)
painter.drawRoundedRect(r, 1, 1)
painter.restore()
return True
return False
def createEditor(self, row, column, item, view):
"""
Create an editing widget for a custom cell
"""
self.currentView = view
currentColumn = self.gCustomColumnList[column]
if currentColumn['cellType'] == 'readonly':
cle = QLabel()
cle.setEnabled(False)
cle.setVisible(False)
return cle
if currentColumn['name'] == 'Colourspace':
cb = QComboBox()
for colourspace in self.gColourSpaces:
cb.addItem(colourspace)
cb.currentIndexChanged.connect(self.colourspaceChanged)
return cb
if currentColumn['name'] == 'Shot Status':
cb = QComboBox()
cb.addItem('')
for key in gStatusTags.keys():
cb.addItem(QIcon(gStatusTags[key]), key)
cb.addItem('--')
cb.currentIndexChanged.connect(self.statusChanged)
return cb
if currentColumn['name'] == 'Artist':
cb = QComboBox()
cb.addItem('')
for artist in gArtistList:
cb.addItem(artist['artistName'])
cb.addItem('--')
cb.currentIndexChanged.connect(self.artistNameChanged)
return cb
return None
def setModelData(self, row, column, item, editor):
return False
def dropMimeData(self, row, column, item, data, items):
"""
Handle a drag and drop operation - adds a Dragged Tag to the shot
"""
for thing in items:
if isinstance(thing, hiero.core.Tag):
item.addTag(thing)
return None
def colourspaceChanged(self, index):
"""
This method is called when Colourspace widget changes index.
"""
index = self.sender().currentIndex()
colourspace = self.gColourSpaces[index]
selection = self.currentView.selection()
project = selection[0].project()
with project.beginUndo("Set Colourspace"):
items = [
item for item in selection
if (item.mediaType() == hiero.core.TrackItem.MediaType.kVideo)
]
for trackItem in items:
trackItem.setSourceMediaColourTransform(colourspace)
def statusChanged(self, arg):
"""
This method is called when Shot Status widget changes index.
"""
view = hiero.ui.activeView()
selection = view.selection()
status = self.sender().currentText()
project = selection[0].project()
with project.beginUndo("Set Status"):
# A string of '--' characters denotes clear the status
if status != '--':
for trackItem in selection:
trackItem.setStatus(status)
else:
for trackItem in selection:
tTags = trackItem.tags()
for tag in tTags:
if tag.metadata().hasKey('tag.status'):
trackItem.removeTag(tag)
break
def artistNameChanged(self, arg):
"""
This method is called when Artist widget changes index.
"""
view = hiero.ui.activeView()
selection = view.selection()
name = self.sender().currentText()
project = selection[0].project()
with project.beginUndo("Assign Artist"):
# A string of '--' denotes clear the assignee...
if name != '--':
for trackItem in selection:
trackItem.setArtistByName(name)
else:
for trackItem in selection:
tTags = trackItem.tags()
for tag in tTags:
if tag.metadata().hasKey('tag.artistID'):
trackItem.removeTag(tag)
break
def _getArtistFromID(self, artistID):
""" getArtistFromID -> returns an artist dictionary, by their given ID"""
global gArtistList
artist = [
element for element in gArtistList
if element['artistID'] == int(artistID)
]
if not artist:
return None
return artist[0]
def _getArtistFromName(self, artistName):
""" getArtistFromID -> returns an artist dictionary, by their given ID """
global gArtistList
artist = [
element for element in gArtistList
if element['artistName'] == artistName
]
if not artist:
return None
return artist[0]
def _artist(self):
"""_artist -> Returns the artist dictionary assigned to this shot"""
artist = None
tags = self.tags()
for tag in tags:
if tag.metadata().hasKey('tag.artistID'):
artistID = tag.metadata().value('tag.artistID')
artist = self.getArtistFromID(artistID)
return artist
def _updateArtistTag(self, artistDict):
# A shot will only have one artist assigned. Check if one exists and set accordingly
artistTag = None
tags = self.tags()
for tag in tags:
if tag.metadata().hasKey('tag.artistID'):
artistTag = tag
break
if not artistTag:
artistTag = hiero.core.Tag('Artist')
artistTag.setIcon(artistDict['artistIcon'])
artistTag.metadata().setValue('tag.artistID',
str(artistDict['artistID']))
artistTag.metadata().setValue('tag.artistName',
str(artistDict['artistName']))
artistTag.metadata().setValue('tag.artistDepartment',
str(artistDict['artistDepartment']))
self.sequence().editFinished()
self.addTag(artistTag)
self.sequence().editFinished()
return
artistTag.setIcon(artistDict['artistIcon'])
artistTag.metadata().setValue('tag.artistID', str(artistDict['artistID']))
artistTag.metadata().setValue('tag.artistName',
str(artistDict['artistName']))
artistTag.metadata().setValue('tag.artistDepartment',
str(artistDict['artistDepartment']))
self.sequence().editFinished()
return
def _setArtistByName(self, artistName):
""" setArtistByName(artistName) -> sets the artist tag on a TrackItem by a given artistName string"""
global gArtistList
artist = self.getArtistFromName(artistName)
if not artist:
print 'Artist name: %s was not found in the gArtistList.' % str(
artistName)
return
# Do the update.
self.updateArtistTag(artist)
def _setArtistByID(self, artistID):
""" setArtistByID(artistID) -> sets the artist tag on a TrackItem by a given artistID integer"""
global gArtistList
artist = self.getArtistFromID(artistID)
if not artist:
print 'Artist name: %s was not found in the gArtistList.' % str(
artistID)
return
# Do the update.
self.updateArtistTag(artist)
# Inject status getter and setter methods into hiero.core.TrackItem
hiero.core.TrackItem.artist = _artist
hiero.core.TrackItem.setArtistByName = _setArtistByName
hiero.core.TrackItem.setArtistByID = _setArtistByID
hiero.core.TrackItem.getArtistFromName = _getArtistFromName
hiero.core.TrackItem.getArtistFromID = _getArtistFromID
hiero.core.TrackItem.updateArtistTag = _updateArtistTag
def _status(self):
"""status -> Returns the Shot status. None if no Status is set."""
status = None
tags = self.tags()
for tag in tags:
if tag.metadata().hasKey('tag.status'):
status = tag.metadata().value('tag.status')
return status
def _setStatus(self, status):
"""setShotStatus(status) -> Method to set the Status of a Shot.
Adds a special kind of status Tag to a TrackItem
Example: myTrackItem.setStatus('Final')
@param status - a string, corresponding to the Status name
"""
global gStatusTags
# Get a valid Tag object from the Global list of statuses
if not status in gStatusTags.keys():
print 'Status requested was not a valid Status string.'
return
# A shot should only have one status. Check if one exists and set accordingly
statusTag = None
tags = self.tags()
for tag in tags:
if tag.metadata().hasKey('tag.status'):
statusTag = tag
break
if not statusTag:
statusTag = hiero.core.Tag('Status')
statusTag.setIcon(gStatusTags[status])
statusTag.metadata().setValue('tag.status', status)
self.addTag(statusTag)
statusTag.setIcon(gStatusTags[status])
statusTag.metadata().setValue('tag.status', status)
self.sequence().editFinished()
return
# Inject status getter and setter methods into hiero.core.TrackItem
hiero.core.TrackItem.setStatus = _setStatus
hiero.core.TrackItem.status = _status
# This is a convenience method for returning QActions with a triggered method based on the title string
def titleStringTriggeredAction(title, method, icon=None):
action = QAction(title, None)
action.setIcon(QIcon(icon))
# We do this magic, so that the title string from the action is used to set the status
def methodWrapper():
method(title)
action.triggered.connect(methodWrapper)
return action
# Menu which adds a Set Status Menu to Timeline and Spreadsheet Views
class SetStatusMenu(QMenu):
def __init__(self):
QMenu.__init__(self, "Set Status", None)
global gStatusTags
self.statuses = gStatusTags
self._statusActions = self.createStatusMenuActions()
# Add the Actions to the Menu.
for act in self.menuActions:
self.addAction(act)
hiero.core.events.registerInterest("kShowContextMenu/kTimeline",
self.eventHandler)
hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet",
self.eventHandler)
def createStatusMenuActions(self):
self.menuActions = []
for status in self.statuses:
self.menuActions += [
titleStringTriggeredAction(
status,
self.setStatusFromMenuSelection,
icon=gStatusTags[status])
]
def setStatusFromMenuSelection(self, menuSelectionStatus):
selectedShots = [
item for item in self._selection
if (isinstance(item, hiero.core.TrackItem))
]
selectedTracks = [
item for item in self._selection
if (isinstance(item, (hiero.core.VideoTrack,
hiero.core.AudioTrack)))
]
# If we have a Track Header Selection, no shots could be selected, so create shotSelection list
if len(selectedTracks) >= 1:
for track in selectedTracks:
selectedShots += [
item for item in track.items()
if (isinstance(item, hiero.core.TrackItem))
]
# It's possible no shots exist on the Track, in which case nothing is required
if len(selectedShots) == 0:
return
currentProject = selectedShots[0].project()
with currentProject.beginUndo("Set Status"):
# Shots selected
for shot in selectedShots:
shot.setStatus(menuSelectionStatus)
# This handles events from the Project Bin View
def eventHandler(self, event):
if not hasattr(event.sender, 'selection'):
# Something has gone wrong, we should only be here if raised
# by the Timeline/Spreadsheet view which gives a selection.
return
# Set the current selection
self._selection = event.sender.selection()
# Return if there's no Selection. We won't add the Menu.
if len(self._selection) == 0:
return
event.menu.addMenu(self)
# Menu which adds a Set Status Menu to Timeline and Spreadsheet Views
class AssignArtistMenu(QMenu):
def __init__(self):
QMenu.__init__(self, "Assign Artist", None)
global gArtistList
self.artists = gArtistList
self._artistsActions = self.createAssignArtistMenuActions()
# Add the Actions to the Menu.
for act in self.menuActions:
self.addAction(act)
hiero.core.events.registerInterest("kShowContextMenu/kTimeline",
self.eventHandler)
hiero.core.events.registerInterest("kShowContextMenu/kSpreadsheet",
self.eventHandler)
def createAssignArtistMenuActions(self):
self.menuActions = []
for artist in self.artists:
self.menuActions += [
titleStringTriggeredAction(
artist['artistName'],
self.setArtistFromMenuSelection,
icon=artist['artistIcon'])
]
def setArtistFromMenuSelection(self, menuSelectionArtist):
selectedShots = [
item for item in self._selection
if (isinstance(item, hiero.core.TrackItem))
]
selectedTracks = [
item for item in self._selection
if (isinstance(item, (hiero.core.VideoTrack,
hiero.core.AudioTrack)))
]
# If we have a Track Header Selection, no shots could be selected, so create shotSelection list
if len(selectedTracks) >= 1:
for track in selectedTracks:
selectedShots += [
item for item in track.items()
if (isinstance(item, hiero.core.TrackItem))
]
# It's possible no shots exist on the Track, in which case nothing is required
if len(selectedShots) == 0:
return
currentProject = selectedShots[0].project()
with currentProject.beginUndo("Assign Artist"):
# Shots selected
for shot in selectedShots:
shot.setArtistByName(menuSelectionArtist)
# This handles events from the Project Bin View
def eventHandler(self, event):
if not hasattr(event.sender, 'selection'):
# Something has gone wrong, we should only be here if raised
# by the Timeline/Spreadsheet view which gives a selection.
return
# Set the current selection
self._selection = event.sender.selection()
# Return if there's no Selection. We won't add the Menu.
if len(self._selection) == 0:
return
event.menu.addMenu(self)
# Add the 'Set Status' context menu to Timeline and Spreadsheet
if kAddStatusMenu:
setStatusMenu = SetStatusMenu()
if kAssignArtistMenu:
assignArtistMenu = AssignArtistMenu()
# Register our custom columns
hiero.ui.customColumn = CustomSpreadsheetColumns()

View file

@ -0,0 +1,142 @@
# Purge Unused Clips - Removes any unused Clips from a Project
# Usage: Copy to ~/.hiero/Python/StartupUI
# Demonstrates the use of hiero.core.find_items module.
# Usage: Right-click on an item in the Bin View > "Purge Unused Clips"
# Result: Any Clips not used in a Sequence in the active project will be removed
# Requires Hiero 1.5v1 or later.
# Version 1.1
import hiero
import hiero.core.find_items
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
class PurgeUnusedAction(QAction):
def __init__(self):
QAction.__init__(self, "Purge Unused Clips", None)
self.triggered.connect(self.PurgeUnused)
hiero.core.events.registerInterest("kShowContextMenu/kBin",
self.eventHandler)
self.setIcon(QIcon('icons:TagDelete.png'))
# Method to return whether a Bin is empty...
def binIsEmpty(self, b):
numBinItems = 0
bItems = b.items()
empty = False
if len(bItems) == 0:
empty = True
return empty
else:
for b in bItems:
if isinstance(b, hiero.core.BinItem) or isinstance(
b, hiero.core.Bin):
numBinItems += 1
if numBinItems == 0:
empty = True
return empty
def PurgeUnused(self):
#Get selected items
item = self.selectedItem
proj = item.project()
# Build a list of Projects
SEQS = hiero.core.findItems(proj, "Sequences")
# Build a list of Clips
CLIPSTOREMOVE = hiero.core.findItems(proj, "Clips")
if len(SEQS) == 0:
# Present Dialog Asking if User wants to remove Clips
msgBox = QMessageBox()
msgBox.setText("Purge Unused Clips")
msgBox.setInformativeText(
"You have no Sequences in this Project. Do you want to remove all Clips (%i) from Project: %s?"
% (len(CLIPSTOREMOVE), proj.name()))
msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msgBox.setDefaultButton(QMessageBox.Ok)
ret = msgBox.exec_()
if ret == QMessageBox.Cancel:
print 'Not purging anything.'
elif ret == QMessageBox.Ok:
with proj.beginUndo('Purge Unused Clips'):
BINS = []
for clip in CLIPSTOREMOVE:
BI = clip.binItem()
B = BI.parentBin()
BINS += [B]
print 'Removing:', BI
try:
B.removeItem(BI)
except:
print 'Unable to remove: ' + BI
return
# For each sequence, iterate through each track Item, see if the Clip is in the CLIPS list.
# Remaining items in CLIPS will be removed
for seq in SEQS:
#Loop through selected and make folders
for track in seq:
for trackitem in track:
if trackitem.source() in CLIPSTOREMOVE:
CLIPSTOREMOVE.remove(trackitem.source())
# Present Dialog Asking if User wants to remove Clips
msgBox = QMessageBox()
msgBox.setText("Purge Unused Clips")
msgBox.setInformativeText("Remove %i unused Clips from Project %s?" %
(len(CLIPSTOREMOVE), proj.name()))
msgBox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
msgBox.setDefaultButton(QMessageBox.Ok)
ret = msgBox.exec_()
if ret == QMessageBox.Cancel:
print 'Cancel'
return
elif ret == QMessageBox.Ok:
BINS = []
with proj.beginUndo('Purge Unused Clips'):
# Delete the rest of the Clips
for clip in CLIPSTOREMOVE:
BI = clip.binItem()
B = BI.parentBin()
BINS += [B]
print 'Removing:', BI
try:
B.removeItem(BI)
except:
print 'Unable to remove: ' + BI
def eventHandler(self, event):
if not hasattr(event.sender, 'selection'):
# Something has gone wrong, we shouldn't only be here if raised
# by the Bin view which will give a selection.
return
self.selectedItem = None
s = event.sender.selection()
if len(s) >= 1:
self.selectedItem = s[0]
title = "Purge Unused Clips"
self.setText(title)
event.menu.addAction(self)
return
# Instantiate the action to get it to register itself.
PurgeUnusedAction = PurgeUnusedAction()

View file

@ -0,0 +1,36 @@
# nukeStyleKeyboardShortcuts, v1, 30/07/2012, Ant Nasce.
# A few Nuke-Style File menu shortcuts for those whose muscle memory has set in...
# Usage: Copy this file to ~/.hiero/Python/StartupUI/
import hiero.ui
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
#----------------------------------------------
a = hiero.ui.findMenuAction('Import Clips...')
# Note: You probably best to make this 'Ctrl+R' - currently conflicts with 'Red' in the Viewer!
a.setShortcut(QKeySequence('R'))
#----------------------------------------------
a = hiero.ui.findMenuAction('Import Folder...')
a.setShortcut(QKeySequence('Shift+R'))
#----------------------------------------------
a = hiero.ui.findMenuAction('Import EDL/XML...')
a.setShortcut(QKeySequence('Ctrl+Shift+O'))
#----------------------------------------------
a = hiero.ui.findMenuAction('Show Metadata')
a.setShortcut(QKeySequence('I'))
#----------------------------------------------
a = hiero.ui.findMenuAction('Edit Settings')
a.setShortcut(QKeySequence('S'))
#----------------------------------------------
a = hiero.ui.findMenuAction('Monitor Controls')
a.setShortcut(QKeySequence('Ctrl+U'))
#----------------------------------------------
a = hiero.ui.findMenuAction('New Viewer')
a.setShortcut(QKeySequence('Ctrl+I'))
#----------------------------------------------

View file

@ -0,0 +1,45 @@
import hiero.core
import hiero.ui
try:
from PySide.QtGui import *
from PySide.QtCore import *
except:
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
def setPosterFrame(posterFrame=.5):
'''
Update the poster frame of the given clipItmes
posterFrame = .5 uses the centre frame, a value of 0 uses the first frame, a value of 1 uses the last frame
'''
view = hiero.ui.activeView()
selectedBinItems = view.selection()
selectedClipItems = [(item.activeItem()
if hasattr(item, 'activeItem') else item)
for item in selectedBinItems]
for clip in selectedClipItems:
centreFrame = int(clip.duration() * posterFrame)
clip.setPosterFrame(centreFrame)
class SetPosterFrameAction(QAction):
def __init__(self):
QAction.__init__(self, "Set Poster Frame (centre)", None)
self._selection = None
self.triggered.connect(lambda: setPosterFrame(.5))
hiero.core.events.registerInterest("kShowContextMenu/kBin",
self.eventHandler)
def eventHandler(self, event):
view = event.sender
# Add the Menu to the right-click menu
event.menu.addAction(self)
# The act of initialising the action adds it to the right-click menu...
SetPosterFrameAction()

View file

@ -0,0 +1,14 @@
import traceback
try:
__import__("pype.nukestudio")
__import__("pyblish")
except ImportError as e:
print traceback.format_exc()
print("pyblish: Could not load integration: %s " % e)
else:
# Setup integration
import pype.nukestudio.lib
pype.nukestudio.lib.setup()

View file

@ -0,0 +1,9 @@
"""Puts the selection project into 'hiero.selection'"""
import hiero
def selectionChanged(event):
hiero.selection = event.sender.selection()
hiero.core.events.registerInterest('kSelectionChanged', selectionChanged)

View file

@ -0,0 +1,198 @@
<root presetname="pipeline" tasktype="hiero.exporters.FnShotProcessor.ShotProcessor">
<startFrameIndex valuetype="int">991</startFrameIndex>
<exportRoot valuetype="str">//10.11.0.184/171001_ftrack/tgbvfx/editorial/nukestudio/workspace/</exportRoot>
<versionIndex valuetype="int">1</versionIndex>
<cutUseHandles valuetype="bool">True</cutUseHandles>
<versionPadding valuetype="int">3</versionPadding>
<exportTemplate valuetype="list">
<SequenceItem valuetype="tuple">
<SequenceItem valuetype="str">{shot}/editorial_raw.%04d.{fileext}</SequenceItem>
<SequenceItem valuetype="hiero.exporters.FnSymLinkExporter.SymLinkPreset">
<root presetname="hiero.exporters.FnSymLinkExporter.SymLinkExporter" tasktype="hiero.exporters.FnSymLinkExporter.SymLinkExporter">
<colourspace valuetype="str">default</colourspace>
<file_type valuetype="unicode">exr</file_type>
<readAllLinesForExport valuetype="bool">False</readAllLinesForExport>
<channels valuetype="str">all</channels>
<includeAudio valuetype="bool">False</includeAudio>
<burninDataEnabled valuetype="bool">False</burninDataEnabled>
<useSingleSocket valuetype="bool">False</useSingleSocket>
<additionalNodesEnabled valuetype="bool">False</additionalNodesEnabled>
<deleteAudio valuetype="bool">True</deleteAudio>
<additionalNodesData valuetype="list" />
<dpx valuetype="dict">
<datatype valuetype="str">8 bit</datatype>
<transfer valuetype="str">(auto detect)</transfer>
<bigEndian valuetype="bool">True</bigEndian>
<fill valuetype="bool">False</fill>
</dpx>
<includeEffects valuetype="bool">False</includeEffects>
<burninData valuetype="dict">
<burnIn_bottomRight valuetype="NoneType">None</burnIn_bottomRight>
<burnIn_topLeft valuetype="NoneType">None</burnIn_topLeft>
<burnIn_topMiddle valuetype="NoneType">None</burnIn_topMiddle>
<burnIn_padding valuetype="NoneType">None</burnIn_padding>
<burnIn_topRight valuetype="NoneType">None</burnIn_topRight>
<burnIn_textSize valuetype="NoneType">None</burnIn_textSize>
<burnIn_bottomLeft valuetype="NoneType">None</burnIn_bottomLeft>
<burnIn_bottomMiddle valuetype="NoneType">None</burnIn_bottomMiddle>
<burnIn_font valuetype="NoneType">None</burnIn_font>
</burninData>
<exr valuetype="dict">
<compression valuetype="str">Zip (16 scanline)</compression>
<datatype valuetype="str">32 bit float</datatype>
<noprefix valuetype="bool">False</noprefix>
<write_full_layer_names valuetype="bool">False</write_full_layer_names>
<standard_layer_name_format valuetype="bool">False</standard_layer_name_format>
<interleave valuetype="str">channels, layers and views</interleave>
<dw_compression_level valuetype="float">45.0</dw_compression_level>
<truncateChannelNames valuetype="bool">False</truncateChannelNames>
<metadata valuetype="str">all metadata</metadata>
</exr>
<writeNodeName valuetype="str">Write_{ext}</writeNodeName>
<reformat valuetype="dict">
<filter valuetype="str">Cubic</filter>
<to_type valuetype="str">None</to_type>
<scale valuetype="float">1.0</scale>
<center valuetype="bool">True</center>
<resize valuetype="str">width</resize>
</reformat>
<keepNukeScript valuetype="bool">False</keepNukeScript>
<method valuetype="str">Blend</method>
</root>
</SequenceItem>
</SequenceItem>
<SequenceItem valuetype="tuple">
<SequenceItem valuetype="str">{shot}/editorial.%04d.{ext}</SequenceItem>
<SequenceItem valuetype="hiero.exporters.FnTranscodeExporter.TranscodePreset">
<root presetname="hiero.exporters.FnTranscodeExporter.TranscodeExporter" tasktype="hiero.exporters.FnTranscodeExporter.TranscodeExporter">
<colourspace valuetype="str">default</colourspace>
<file_type valuetype="unicode">exr</file_type>
<readAllLinesForExport valuetype="bool">False</readAllLinesForExport>
<channels valuetype="str">all</channels>
<includeAudio valuetype="bool">False</includeAudio>
<burninDataEnabled valuetype="bool">False</burninDataEnabled>
<useSingleSocket valuetype="bool">False</useSingleSocket>
<additionalNodesEnabled valuetype="bool">False</additionalNodesEnabled>
<deleteAudio valuetype="bool">True</deleteAudio>
<additionalNodesData valuetype="list" />
<dpx valuetype="dict">
<datatype valuetype="str">8 bit</datatype>
<transfer valuetype="str">(auto detect)</transfer>
<bigEndian valuetype="bool">True</bigEndian>
<fill valuetype="bool">False</fill>
</dpx>
<includeEffects valuetype="bool">True</includeEffects>
<burninData valuetype="dict">
<burnIn_bottomRight valuetype="NoneType">None</burnIn_bottomRight>
<burnIn_topLeft valuetype="NoneType">None</burnIn_topLeft>
<burnIn_topMiddle valuetype="NoneType">None</burnIn_topMiddle>
<burnIn_padding valuetype="NoneType">None</burnIn_padding>
<burnIn_topRight valuetype="NoneType">None</burnIn_topRight>
<burnIn_textSize valuetype="NoneType">None</burnIn_textSize>
<burnIn_bottomLeft valuetype="NoneType">None</burnIn_bottomLeft>
<burnIn_bottomMiddle valuetype="NoneType">None</burnIn_bottomMiddle>
<burnIn_font valuetype="NoneType">None</burnIn_font>
</burninData>
<exr valuetype="dict">
<compression valuetype="str">Zip (16 scanline)</compression>
<datatype valuetype="str">16 bit half</datatype>
<noprefix valuetype="bool">False</noprefix>
<write_full_layer_names valuetype="bool">False</write_full_layer_names>
<standard_layer_name_format valuetype="bool">False</standard_layer_name_format>
<interleave valuetype="str">channels, layers and views</interleave>
<dw_compression_level valuetype="float">45.0</dw_compression_level>
<truncateChannelNames valuetype="bool">False</truncateChannelNames>
<metadata valuetype="str">all metadata</metadata>
</exr>
<writeNodeName valuetype="str">Write_{ext}</writeNodeName>
<reformat valuetype="dict">
<filter valuetype="str">Cubic</filter>
<to_type valuetype="str">To Sequence Resolution</to_type>
<scale valuetype="float">1.0</scale>
<center valuetype="bool">True</center>
<resize valuetype="str">width</resize>
</reformat>
<keepNukeScript valuetype="bool">False</keepNukeScript>
<method valuetype="str">Blend</method>
</root>
</SequenceItem>
</SequenceItem>
<SequenceItem valuetype="tuple">
<SequenceItem valuetype="str">{shot}/editorial.nk</SequenceItem>
<SequenceItem valuetype="hiero.exporters.FnNukeShotExporter.NukeShotPreset">
<root presetname="hiero.exporters.FnNukeShotExporter.NukeShotExporter" tasktype="hiero.exporters.FnNukeShotExporter.NukeShotExporter">
<postProcessScript valuetype="bool">True</postProcessScript>
<colourspace valuetype="str">default</colourspace>
<file_type valuetype="unicode">mov</file_type>
<annotationsPreCompPaths valuetype="list" />
<channels valuetype="str">rgb</channels>
<includeAudio valuetype="bool">False</includeAudio>
<readPaths valuetype="list" />
<connectTracks valuetype="bool">False</connectTracks>
<useSingleSocket valuetype="bool">False</useSingleSocket>
<collateSequence valuetype="bool">False</collateSequence>
<additionalNodesData valuetype="list" />
<collateShotNames valuetype="bool">True</collateShotNames>
<includeEffects valuetype="bool">True</includeEffects>
<writePaths valuetype="list">
<SequenceItem valuetype="str">{shot}/editorial_raw.%04d.{fileext}</SequenceItem>
</writePaths>
<reformat valuetype="dict">
<filter valuetype="str">Cubic</filter>
<to_type valuetype="str">None</to_type>
<scale valuetype="float">1.0</scale>
<center valuetype="bool">True</center>
<resize valuetype="str">width</resize>
</reformat>
<keepNukeScript valuetype="bool">False</keepNukeScript>
<method valuetype="str">Blend</method>
<includeAnnotations valuetype="bool">False</includeAnnotations>
<enable valuetype="bool">True</enable>
<showAnnotations valuetype="bool">True</showAnnotations>
<mov valuetype="dict">
<b_frames valuetype="int">0</b_frames>
<bitrate_tolerance valuetype="int">40000000</bitrate_tolerance>
<gop_size valuetype="int">12</gop_size>
<quality_max valuetype="int">31</quality_max>
<quality_min valuetype="int">2</quality_min>
<codec valuetype="str">avc1&#x09;H.264</codec>
<ycbcr_matrix_type valuetype="str">Auto</ycbcr_matrix_type>
<encoder valuetype="str">mov32</encoder>
<bitrate valuetype="int">20000</bitrate>
</mov>
<readAllLinesForExport valuetype="bool">False</readAllLinesForExport>
<deleteAudio valuetype="bool">True</deleteAudio>
<collateCustomStart valuetype="bool">True</collateCustomStart>
<burninDataEnabled valuetype="bool">False</burninDataEnabled>
<additionalNodesEnabled valuetype="bool">False</additionalNodesEnabled>
<timelineWriteNode valuetype="str">{shot}/editorial_raw.%04d.{fileext}</timelineWriteNode>
<burninData valuetype="dict">
<burnIn_bottomRight valuetype="NoneType">None</burnIn_bottomRight>
<burnIn_topLeft valuetype="NoneType">None</burnIn_topLeft>
<burnIn_topMiddle valuetype="NoneType">None</burnIn_topMiddle>
<burnIn_padding valuetype="NoneType">None</burnIn_padding>
<burnIn_topRight valuetype="NoneType">None</burnIn_topRight>
<burnIn_bottomMiddle valuetype="NoneType">None</burnIn_bottomMiddle>
<burnIn_bottomLeft valuetype="NoneType">None</burnIn_bottomLeft>
<burnIn_textSize valuetype="NoneType">None</burnIn_textSize>
<burnIn_font valuetype="NoneType">None</burnIn_font>
</burninData>
<dpx valuetype="dict">
<datatype valuetype="str">8 bit</datatype>
<transfer valuetype="str">(auto detect)</transfer>
<bigEndian valuetype="bool">True</bigEndian>
<fill valuetype="bool">False</fill>
</dpx>
<writeNodeName valuetype="str">Write_{ext}</writeNodeName>
<collateTracks valuetype="bool">False</collateTracks>
</root>
</SequenceItem>
</SequenceItem>
</exportTemplate>
<excludeTags valuetype="list" />
<includeTags valuetype="list" />
<includeRetimes valuetype="bool">False</includeRetimes>
<startFrameSource valuetype="str">Custom</startFrameSource>
<cutLength valuetype="bool">True</cutLength>
<cutHandles valuetype="int">10</cutHandles>
</root>

View file

@ -0,0 +1,198 @@
<root presetname="pipeline" tasktype="hiero.exporters.FnShotProcessor.ShotProcessor">
<startFrameIndex valuetype="int">991</startFrameIndex>
<exportRoot valuetype="str">//10.11.0.184/171001_ftrack/tgbvfx/editorial/nukestudio/workspace/</exportRoot>
<versionIndex valuetype="int">1</versionIndex>
<cutUseHandles valuetype="bool">True</cutUseHandles>
<versionPadding valuetype="int">3</versionPadding>
<exportTemplate valuetype="list">
<SequenceItem valuetype="tuple">
<SequenceItem valuetype="str">{shot}/editorial_raw.%04d.{fileext}</SequenceItem>
<SequenceItem valuetype="hiero.exporters.FnSymLinkExporter.SymLinkPreset">
<root presetname="hiero.exporters.FnSymLinkExporter.SymLinkExporter" tasktype="hiero.exporters.FnSymLinkExporter.SymLinkExporter">
<colourspace valuetype="str">default</colourspace>
<file_type valuetype="unicode">exr</file_type>
<readAllLinesForExport valuetype="bool">False</readAllLinesForExport>
<channels valuetype="str">all</channels>
<includeAudio valuetype="bool">False</includeAudio>
<burninDataEnabled valuetype="bool">False</burninDataEnabled>
<useSingleSocket valuetype="bool">False</useSingleSocket>
<additionalNodesEnabled valuetype="bool">False</additionalNodesEnabled>
<deleteAudio valuetype="bool">True</deleteAudio>
<additionalNodesData valuetype="list" />
<dpx valuetype="dict">
<datatype valuetype="str">8 bit</datatype>
<transfer valuetype="str">(auto detect)</transfer>
<bigEndian valuetype="bool">True</bigEndian>
<fill valuetype="bool">False</fill>
</dpx>
<includeEffects valuetype="bool">False</includeEffects>
<burninData valuetype="dict">
<burnIn_bottomRight valuetype="NoneType">None</burnIn_bottomRight>
<burnIn_topLeft valuetype="NoneType">None</burnIn_topLeft>
<burnIn_topMiddle valuetype="NoneType">None</burnIn_topMiddle>
<burnIn_padding valuetype="NoneType">None</burnIn_padding>
<burnIn_topRight valuetype="NoneType">None</burnIn_topRight>
<burnIn_textSize valuetype="NoneType">None</burnIn_textSize>
<burnIn_bottomLeft valuetype="NoneType">None</burnIn_bottomLeft>
<burnIn_bottomMiddle valuetype="NoneType">None</burnIn_bottomMiddle>
<burnIn_font valuetype="NoneType">None</burnIn_font>
</burninData>
<exr valuetype="dict">
<compression valuetype="str">Zip (16 scanline)</compression>
<datatype valuetype="str">32 bit float</datatype>
<noprefix valuetype="bool">False</noprefix>
<write_full_layer_names valuetype="bool">False</write_full_layer_names>
<standard_layer_name_format valuetype="bool">False</standard_layer_name_format>
<interleave valuetype="str">channels, layers and views</interleave>
<dw_compression_level valuetype="float">45.0</dw_compression_level>
<truncateChannelNames valuetype="bool">False</truncateChannelNames>
<metadata valuetype="str">all metadata</metadata>
</exr>
<writeNodeName valuetype="str">Write_{ext}</writeNodeName>
<reformat valuetype="dict">
<filter valuetype="str">Cubic</filter>
<to_type valuetype="str">None</to_type>
<scale valuetype="float">1.0</scale>
<center valuetype="bool">True</center>
<resize valuetype="str">width</resize>
</reformat>
<keepNukeScript valuetype="bool">False</keepNukeScript>
<method valuetype="str">Blend</method>
</root>
</SequenceItem>
</SequenceItem>
<SequenceItem valuetype="tuple">
<SequenceItem valuetype="str">{shot}/editorial.%04d.{ext}</SequenceItem>
<SequenceItem valuetype="hiero.exporters.FnTranscodeExporter.TranscodePreset">
<root presetname="hiero.exporters.FnTranscodeExporter.TranscodeExporter" tasktype="hiero.exporters.FnTranscodeExporter.TranscodeExporter">
<colourspace valuetype="str">default</colourspace>
<file_type valuetype="unicode">exr</file_type>
<readAllLinesForExport valuetype="bool">False</readAllLinesForExport>
<channels valuetype="str">all</channels>
<includeAudio valuetype="bool">False</includeAudio>
<burninDataEnabled valuetype="bool">False</burninDataEnabled>
<useSingleSocket valuetype="bool">False</useSingleSocket>
<additionalNodesEnabled valuetype="bool">False</additionalNodesEnabled>
<deleteAudio valuetype="bool">True</deleteAudio>
<additionalNodesData valuetype="list" />
<dpx valuetype="dict">
<datatype valuetype="str">8 bit</datatype>
<transfer valuetype="str">(auto detect)</transfer>
<bigEndian valuetype="bool">True</bigEndian>
<fill valuetype="bool">False</fill>
</dpx>
<includeEffects valuetype="bool">True</includeEffects>
<burninData valuetype="dict">
<burnIn_bottomRight valuetype="NoneType">None</burnIn_bottomRight>
<burnIn_topLeft valuetype="NoneType">None</burnIn_topLeft>
<burnIn_topMiddle valuetype="NoneType">None</burnIn_topMiddle>
<burnIn_padding valuetype="NoneType">None</burnIn_padding>
<burnIn_topRight valuetype="NoneType">None</burnIn_topRight>
<burnIn_textSize valuetype="NoneType">None</burnIn_textSize>
<burnIn_bottomLeft valuetype="NoneType">None</burnIn_bottomLeft>
<burnIn_bottomMiddle valuetype="NoneType">None</burnIn_bottomMiddle>
<burnIn_font valuetype="NoneType">None</burnIn_font>
</burninData>
<exr valuetype="dict">
<compression valuetype="str">Zip (16 scanline)</compression>
<datatype valuetype="str">16 bit half</datatype>
<noprefix valuetype="bool">False</noprefix>
<write_full_layer_names valuetype="bool">False</write_full_layer_names>
<standard_layer_name_format valuetype="bool">False</standard_layer_name_format>
<interleave valuetype="str">channels, layers and views</interleave>
<dw_compression_level valuetype="float">45.0</dw_compression_level>
<truncateChannelNames valuetype="bool">False</truncateChannelNames>
<metadata valuetype="str">all metadata</metadata>
</exr>
<writeNodeName valuetype="str">Write_{ext}</writeNodeName>
<reformat valuetype="dict">
<filter valuetype="str">Cubic</filter>
<to_type valuetype="str">To Sequence Resolution</to_type>
<scale valuetype="float">1.0</scale>
<center valuetype="bool">True</center>
<resize valuetype="str">width</resize>
</reformat>
<keepNukeScript valuetype="bool">False</keepNukeScript>
<method valuetype="str">Blend</method>
</root>
</SequenceItem>
</SequenceItem>
<SequenceItem valuetype="tuple">
<SequenceItem valuetype="str">{shot}/editorial.nk</SequenceItem>
<SequenceItem valuetype="hiero.exporters.FnNukeShotExporter.NukeShotPreset">
<root presetname="hiero.exporters.FnNukeShotExporter.NukeShotExporter" tasktype="hiero.exporters.FnNukeShotExporter.NukeShotExporter">
<postProcessScript valuetype="bool">True</postProcessScript>
<colourspace valuetype="str">default</colourspace>
<file_type valuetype="unicode">mov</file_type>
<annotationsPreCompPaths valuetype="list" />
<channels valuetype="str">rgb</channels>
<includeAudio valuetype="bool">False</includeAudio>
<readPaths valuetype="list" />
<connectTracks valuetype="bool">False</connectTracks>
<useSingleSocket valuetype="bool">False</useSingleSocket>
<collateSequence valuetype="bool">False</collateSequence>
<additionalNodesData valuetype="list" />
<collateShotNames valuetype="bool">True</collateShotNames>
<includeEffects valuetype="bool">True</includeEffects>
<writePaths valuetype="list">
<SequenceItem valuetype="str">{shot}/editorial_raw.%04d.{fileext}</SequenceItem>
</writePaths>
<reformat valuetype="dict">
<filter valuetype="str">Cubic</filter>
<to_type valuetype="str">None</to_type>
<scale valuetype="float">1.0</scale>
<center valuetype="bool">True</center>
<resize valuetype="str">width</resize>
</reformat>
<keepNukeScript valuetype="bool">False</keepNukeScript>
<method valuetype="str">Blend</method>
<includeAnnotations valuetype="bool">False</includeAnnotations>
<enable valuetype="bool">True</enable>
<showAnnotations valuetype="bool">True</showAnnotations>
<mov valuetype="dict">
<b_frames valuetype="int">0</b_frames>
<bitrate_tolerance valuetype="int">40000000</bitrate_tolerance>
<gop_size valuetype="int">12</gop_size>
<quality_max valuetype="int">31</quality_max>
<quality_min valuetype="int">2</quality_min>
<codec valuetype="str">avc1&#x09;H.264</codec>
<ycbcr_matrix_type valuetype="str">Auto</ycbcr_matrix_type>
<encoder valuetype="str">mov32</encoder>
<bitrate valuetype="int">20000</bitrate>
</mov>
<readAllLinesForExport valuetype="bool">False</readAllLinesForExport>
<deleteAudio valuetype="bool">True</deleteAudio>
<collateCustomStart valuetype="bool">True</collateCustomStart>
<burninDataEnabled valuetype="bool">False</burninDataEnabled>
<additionalNodesEnabled valuetype="bool">False</additionalNodesEnabled>
<timelineWriteNode valuetype="str">{shot}/editorial_raw.%04d.{fileext}</timelineWriteNode>
<burninData valuetype="dict">
<burnIn_bottomRight valuetype="NoneType">None</burnIn_bottomRight>
<burnIn_topLeft valuetype="NoneType">None</burnIn_topLeft>
<burnIn_topMiddle valuetype="NoneType">None</burnIn_topMiddle>
<burnIn_padding valuetype="NoneType">None</burnIn_padding>
<burnIn_topRight valuetype="NoneType">None</burnIn_topRight>
<burnIn_bottomMiddle valuetype="NoneType">None</burnIn_bottomMiddle>
<burnIn_bottomLeft valuetype="NoneType">None</burnIn_bottomLeft>
<burnIn_textSize valuetype="NoneType">None</burnIn_textSize>
<burnIn_font valuetype="NoneType">None</burnIn_font>
</burninData>
<dpx valuetype="dict">
<datatype valuetype="str">8 bit</datatype>
<transfer valuetype="str">(auto detect)</transfer>
<bigEndian valuetype="bool">True</bigEndian>
<fill valuetype="bool">False</fill>
</dpx>
<writeNodeName valuetype="str">Write_{ext}</writeNodeName>
<collateTracks valuetype="bool">False</collateTracks>
</root>
</SequenceItem>
</SequenceItem>
</exportTemplate>
<excludeTags valuetype="list" />
<includeTags valuetype="list" />
<includeRetimes valuetype="bool">False</includeRetimes>
<startFrameSource valuetype="str">Custom</startFrameSource>
<cutLength valuetype="bool">True</cutLength>
<cutHandles valuetype="int">10</cutHandles>
</root>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hieroXML>
<hieroXML version="10" revision="159" release="10.5v1" name="Hiero">
<Project guid="{26e11125-2da7-a24c-a2d2-8ff1e43f0076}" floatLut="ACES - ACES2065-1" ocioConfigName="aces_1.0.1" logLut="Input - ARRI - V3 LogC (EI800) - Wide Gamut" workingSpace="ACES - ACEScg" name="test" timedisplayformat="0" starttimecode="86400" shotPresetName="Basic Nuke Shot With Annotations" redVideoDecodeMode="0" sixteenBitLut="Utility - sRGB - Texture" nukeUseOCIO="1" samplerate="48000/1" framerate="24/1" timelineReformatType="Disabled" viewerLut="ACES/sRGB D60 sim." ocioConfigCustom="0" thumbnailLut="ACES/sRGB D60 sim." buildTrackName="VFX" ocioconfigpath="V:/Remote Apps/Nuke10.5v1/plugins/OCIOConfigs/configs/aces_1.0.1/config.ocio" timelineReformatCenter="1" useViewColors="0" editable="1" timelineReformatResizeType="Width" eightBitLut="Utility - sRGB - Texture">
<items>
<RootBinProjectItem editable="1" guid="{5a73c3ce-0194-f748-93cf-e0314c94e512}" name="Sequences">
<items>
<BinProjectItem editable="1" guid="{a0af2960-f7a7-d24e-a841-b8a6a754611a}" name="in">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
</BinProjectItem>
<BinProjectItem editable="1" guid="{b49aa641-6b2c-f74b-92e5-9b79105ef212}" name="out">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
</BinProjectItem>
</items>
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>13</AllowedItems>
</RootBinProjectItem>
<RootBinProjectItem editable="1" guid="{a0df9e8c-cdef-7a41-a818-a7437ca86567}" name="Tags">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>17</AllowedItems>
</RootBinProjectItem>
</items>
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>2</AllowedItems>
<RootBinProjectItem objName="sequencesBin" guid="{5a73c3ce-0194-f748-93cf-e0314c94e512}" link="internal"/>
<RootBinProjectItem objName="tagsBin" guid="{a0df9e8c-cdef-7a41-a818-a7437ca86567}" link="internal"/>
<MediaFormatValue default="0" objName="outputformat" value="1,[ 0, 0, 1920, 1080],[ 0, 0, 1920, 1080],HD_1080" name=""/>
<Views>
<View name="main" color="#ffffff"/>
</Views>
</Project>
<UIState/>
</hieroXML>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hieroXML>
<hieroXML version="10" revision="159" release="10.5v1" name="Hiero">
<Project guid="{26e11125-2da7-a24c-a2d2-8ff1e43f0076}" floatLut="linear" ocioConfigName="custom" logLut="Cineon" workingSpace="linear" name="vfx_linear" timedisplayformat="0" starttimecode="86400" shotPresetName="Basic Nuke Shot With Annotations" redVideoDecodeMode="0" sixteenBitLut="sRGB" nukeUseOCIO="0" samplerate="48000/1" framerate="24/1" timelineReformatType="Disabled" viewerLut="sRGB" ocioConfigCustom="0" thumbnailLut="sRGB" buildTrackName="VFX" ocioconfigpath="" timelineReformatCenter="1" useViewColors="0" editable="1" timelineReformatResizeType="Width" eightBitLut="sRGB">
<items>
<RootBinProjectItem editable="1" guid="{5a73c3ce-0194-f748-93cf-e0314c94e512}" name="Sequences">
<items>
<BinProjectItem editable="1" guid="{a0af2960-f7a7-d24e-a841-b8a6a754611a}" name="in">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
</BinProjectItem>
<BinProjectItem editable="1" guid="{b49aa641-6b2c-f74b-92e5-9b79105ef212}" name="out">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
</BinProjectItem>
</items>
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>13</AllowedItems>
</RootBinProjectItem>
<RootBinProjectItem editable="1" guid="{a0df9e8c-cdef-7a41-a818-a7437ca86567}" name="Tags">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>17</AllowedItems>
</RootBinProjectItem>
</items>
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>2</AllowedItems>
<RootBinProjectItem objName="sequencesBin" guid="{5a73c3ce-0194-f748-93cf-e0314c94e512}" link="internal"/>
<RootBinProjectItem objName="tagsBin" guid="{a0df9e8c-cdef-7a41-a818-a7437ca86567}" link="internal"/>
<MediaFormatValue default="0" objName="outputformat" value="1,[ 0, 0, 1920, 1080],[ 0, 0, 1920, 1080],HD_1080" name=""/>
<Views>
<View name="main" color="#ffffff"/>
</Views>
</Project>
<UIState/>
</hieroXML>

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hieroXML>
<hieroXML version="10" revision="159" release="10.5v1" name="Hiero">
<Project guid="{26e11125-2da7-a24c-a2d2-8ff1e43f0076}" floatLut="linear" ocioConfigName="custom" logLut="AlexaV3LogC" workingSpace="rec709" name="vfx_rec709" timedisplayformat="0" starttimecode="86400" shotPresetName="Basic Nuke Shot With Annotations" redVideoDecodeMode="0" sixteenBitLut="rec709" nukeUseOCIO="0" samplerate="48000/1" framerate="24/1" timelineReformatType="Disabled" viewerLut="rec709" ocioConfigCustom="0" thumbnailLut="sRGB" buildTrackName="VFX" ocioconfigpath="" timelineReformatCenter="1" useViewColors="0" editable="1" timelineReformatResizeType="Width" eightBitLut="sRGB">
<items>
<RootBinProjectItem editable="1" guid="{5a73c3ce-0194-f748-93cf-e0314c94e512}" name="Sequences">
<items>
<BinProjectItem editable="1" guid="{a0af2960-f7a7-d24e-a841-b8a6a754611a}" name="in">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
</BinProjectItem>
<BinProjectItem editable="1" guid="{b49aa641-6b2c-f74b-92e5-9b79105ef212}" name="out">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
</BinProjectItem>
</items>
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>13</AllowedItems>
</RootBinProjectItem>
<RootBinProjectItem editable="1" guid="{a0df9e8c-cdef-7a41-a818-a7437ca86567}" name="Tags">
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>17</AllowedItems>
</RootBinProjectItem>
</items>
<BinViewType>2</BinViewType>
<BinViewZoom>70</BinViewZoom>
<AllowedItems>2</AllowedItems>
<RootBinProjectItem objName="sequencesBin" guid="{5a73c3ce-0194-f748-93cf-e0314c94e512}" link="internal"/>
<RootBinProjectItem objName="tagsBin" guid="{a0df9e8c-cdef-7a41-a818-a7437ca86567}" link="internal"/>
<MediaFormatValue default="0" objName="outputformat" value="1,[ 0, 0, 1920, 1080],[ 0, 0, 1920, 1080],HD_1080" name=""/>
<Views>
<View name="main" color="#ffffff"/>
</Views>
</Project>
<UIState/>
</hieroXML>