mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
adding additional integration modules
This commit is contained in:
parent
ca92c42cde
commit
6188223567
17 changed files with 3446 additions and 51 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
1108
setup/nukestudio/hiero_plugin_path/HieroPlayer/PlayerPresets.hrox
Normal file
1108
setup/nukestudio/hiero_plugin_path/HieroPlayer/PlayerPresets.hrox
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
142
setup/nukestudio/hiero_plugin_path/Python/StartupUI/Purge.py
Normal file
142
setup/nukestudio/hiero_plugin_path/Python/StartupUI/Purge.py
Normal 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()
|
||||
|
|
@ -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'))
|
||||
#----------------------------------------------
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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)
|
||||
|
|
@ -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	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>
|
||||
|
|
@ -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	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>
|
||||
38
setup/nukestudio/hiero_plugin_path/Templates/vfx_aces.hrox
Normal file
38
setup/nukestudio/hiero_plugin_path/Templates/vfx_aces.hrox
Normal 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>
|
||||
38
setup/nukestudio/hiero_plugin_path/Templates/vfx_linear.hrox
Normal file
38
setup/nukestudio/hiero_plugin_path/Templates/vfx_linear.hrox
Normal 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>
|
||||
38
setup/nukestudio/hiero_plugin_path/Templates/vfx_rec709.hrox
Normal file
38
setup/nukestudio/hiero_plugin_path/Templates/vfx_rec709.hrox
Normal 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>
|
||||
Loading…
Add table
Add a link
Reference in a new issue