Merged in feature/PYPE-338-publish-representations-for-sho (pull request #155)
Feature/PYPE-338 publish representations for sho Approved-by: Jakub Jezek <jezschaj@gmail.com>
|
|
@ -1,6 +1,6 @@
|
|||
from hiero.core import *
|
||||
from hiero.ui import *
|
||||
import ft_utils
|
||||
import hiero.core
|
||||
import hiero.ui
|
||||
|
||||
import re
|
||||
import os
|
||||
|
||||
|
|
@ -11,31 +11,30 @@ def create_nk_script_clips(script_lst, seq=None):
|
|||
[{
|
||||
'path': 'P:/Jakub_testy_pipeline/test_v01.nk',
|
||||
'name': 'test',
|
||||
'timeline_frame_in': 10,
|
||||
'handles': 10,
|
||||
'source_start': 0,
|
||||
'source_end': 54,
|
||||
'handleStart': 15, # added asymetrically to handles
|
||||
'handleEnd': 10, # added asymetrically to handles
|
||||
'timelineIn': 16,
|
||||
'startFrame': 991,
|
||||
'endFrame': 1023,
|
||||
'task': 'Comp-tracking',
|
||||
'work_dir': 'VFX_PR',
|
||||
'shot': '00010'
|
||||
}]
|
||||
'''
|
||||
env = ft_utils.Env()
|
||||
proj = projects()[-1]
|
||||
|
||||
proj = hiero.core.projects()[-1]
|
||||
root = proj.clipsBin()
|
||||
|
||||
if not seq:
|
||||
seq = Sequence('NewSequences')
|
||||
root.addItem(BinItem(seq))
|
||||
seq = hiero.core.Sequence('NewSequences')
|
||||
root.addItem(hiero.core.BinItem(seq))
|
||||
# todo will ned to define this better
|
||||
# track = seq[1] # lazy example to get a destination# track
|
||||
clips_lst = []
|
||||
for nk in script_lst:
|
||||
task_short = env.task_codes[nk['task']]
|
||||
script_file = task_short
|
||||
task_path = '/'.join([nk['work_dir'], nk['shot'], nk['task']])
|
||||
bin = create_bin_in_project(task_path, proj)
|
||||
task_path += script_file
|
||||
|
||||
if nk['task'] not in seq.videoTracks():
|
||||
track = hiero.core.VideoTrack(nk['task'])
|
||||
|
|
@ -44,33 +43,63 @@ def create_nk_script_clips(script_lst, seq=None):
|
|||
track = seq.tracks(nk['task'])
|
||||
|
||||
# create slip media
|
||||
print nk['path']
|
||||
media = MediaSource(nk['path'])
|
||||
print media
|
||||
source = Clip(media)
|
||||
print source
|
||||
print("__ path: `{}`".format(nk['path']))
|
||||
|
||||
media = hiero.core.MediaSource(nk['path'])
|
||||
media_in = int(media.startTime() or 0)
|
||||
media_duration = int(media.duration() or 0)
|
||||
|
||||
handle_start = nk.get("handleStart") or nk['handles']
|
||||
handle_end = nk.get("handleEnd") or nk['handles']
|
||||
|
||||
if media_in:
|
||||
source_in = media_in + handle_start
|
||||
else:
|
||||
source_in = nk['startFrame'] + handle_start
|
||||
|
||||
if media_duration:
|
||||
source_out = (media_in + media_duration - 1) - handle_end
|
||||
else:
|
||||
source_out = nk['endFrame'] - handle_end
|
||||
|
||||
print("__ media: `{}`".format(media))
|
||||
print("__ media_in: `{}`".format(media_in))
|
||||
print("__ media_duration : `{}`".format(media_duration))
|
||||
print("__ source_in: `{}`".format(source_in))
|
||||
print("__ source_out : `{}`".format(source_out))
|
||||
|
||||
source = hiero.core.Clip(media)
|
||||
print("__ source : `{}`".format(source))
|
||||
print("__ source.sourceIn(): `{}`".format(source.sourceIn()))
|
||||
|
||||
name = os.path.basename(os.path.splitext(nk['path'])[0])
|
||||
split_name = split_by_client_version(name, env)[0] or name
|
||||
print split_name
|
||||
# print source
|
||||
split_name = split_by_client_version(name)[0] or name
|
||||
|
||||
print("__ split_name: `{}`".format(split_name))
|
||||
|
||||
# add to bin as clip item
|
||||
items_in_bin = [b.name() for b in bin.items()]
|
||||
if split_name not in items_in_bin:
|
||||
binItem = BinItem(source)
|
||||
binItem = hiero.core.BinItem(source)
|
||||
bin.addItem(binItem)
|
||||
print bin.items()
|
||||
|
||||
print("__ bin.items(): `{}`".format(bin.items()))
|
||||
|
||||
new_source = [
|
||||
item for item in bin.items() if split_name in item.name()
|
||||
][0].items()[0].item()
|
||||
print new_source
|
||||
|
||||
print("__ new_source: `{}`".format(new_source))
|
||||
print("__ new_source: `{}`".format(new_source))
|
||||
|
||||
# add to track as clip item
|
||||
trackItem = TrackItem(split_name, TrackItem.kVideo)
|
||||
trackItem = hiero.core.TrackItem(split_name, hiero.core.TrackItem.kVideo)
|
||||
trackItem.setSource(new_source)
|
||||
trackItem.setSourceIn(nk['source_start'] + nk['handles'])
|
||||
trackItem.setSourceOut(nk['source_end'] - nk['handles'])
|
||||
trackItem.setTimelineIn(nk['source_start'] + nk['timeline_frame_in'])
|
||||
trackItem.setTimelineOut(
|
||||
(nk['source_end'] - (nk['handles'] * 2)) + nk['timeline_frame_in'])
|
||||
trackItem.setSourceIn(source_in)
|
||||
trackItem.setSourceOut(source_out)
|
||||
trackItem.setSourceIn(source_in)
|
||||
trackItem.setTimelineIn(nk['timelineIn'])
|
||||
trackItem.setTimelineOut(nk['timelineIn'] + (source_out - source_in))
|
||||
track.addTrackItem(trackItem)
|
||||
track.addTrackItem(trackItem)
|
||||
clips_lst.append(trackItem)
|
||||
|
|
@ -86,7 +115,7 @@ def create_bin_in_project(bin_name='', project=''):
|
|||
|
||||
if not project:
|
||||
# get the first loaded project
|
||||
project = projects()[0]
|
||||
project = hiero.core.projects()[-1]
|
||||
if not bin_name:
|
||||
return None
|
||||
if '/' in bin_name:
|
||||
|
|
@ -103,7 +132,7 @@ def create_bin_in_project(bin_name='', project=''):
|
|||
bin = [bin for bin in clipsBin.bins() if b in bin.name()][0]
|
||||
done_bin_lst.append(bin)
|
||||
else:
|
||||
create_bin = Bin(b)
|
||||
create_bin = hiero.core.Bin(b)
|
||||
clipsBin.addItem(create_bin)
|
||||
done_bin_lst.append(create_bin)
|
||||
|
||||
|
|
@ -115,7 +144,7 @@ def create_bin_in_project(bin_name='', project=''):
|
|||
][0]
|
||||
done_bin_lst.append(bin)
|
||||
else:
|
||||
create_bin = Bin(b)
|
||||
create_bin = hiero.core.Bin(b)
|
||||
done_bin_lst[i - 1].addItem(create_bin)
|
||||
done_bin_lst.append(create_bin)
|
||||
|
||||
|
|
@ -127,22 +156,33 @@ def create_bin_in_project(bin_name='', project=''):
|
|||
][0]
|
||||
done_bin_lst.append(bin)
|
||||
else:
|
||||
create_bin = Bin(b)
|
||||
create_bin = hiero.core.Bin(b)
|
||||
done_bin_lst[i - 1].addItem(create_bin)
|
||||
done_bin_lst.append(create_bin)
|
||||
# print [bin.name() for bin in clipsBin.bins()]
|
||||
return done_bin_lst[-1]
|
||||
|
||||
|
||||
def split_by_client_version(string, env=None):
|
||||
if not env:
|
||||
env = ft_utils.Env()
|
||||
|
||||
client_letter, client_digits = env.get_version_type('client')
|
||||
regex = "[/_.]" + client_letter + "\d+"
|
||||
def split_by_client_version(string):
|
||||
regex = r"[/_.]v\d+"
|
||||
try:
|
||||
matches = re.findall(regex, string, re.IGNORECASE)
|
||||
return string.split(matches[0])
|
||||
except Exception, e:
|
||||
print e
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return None
|
||||
|
||||
|
||||
script_lst = [{
|
||||
'path': 'C:/Users/hubert/_PYPE_testing/projects/D001_projectx/episodes/ep120/ep120sq01/120sh020/publish/plates/platesMain/v023/prjx_120sh020_platesMain_v023.nk',
|
||||
'name': '120sh020_platesMain',
|
||||
'handles': 10,
|
||||
'handleStart': 10,
|
||||
'handleEnd': 10,
|
||||
'timelineIn': 16,
|
||||
'startFrame': 991,
|
||||
'endFrame': 1023,
|
||||
'task': 'platesMain',
|
||||
'work_dir': 'shots',
|
||||
'shot': '120sh020'
|
||||
}]
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ def update_tag(tag, value):
|
|||
"""
|
||||
|
||||
tag.setNote(value['note'])
|
||||
tag.setIcon(value['icon']['path'])
|
||||
tag.setIcon(str(value['icon']['path']))
|
||||
mtd = tag.metadata()
|
||||
pres_mtd = value.get('metadata', None)
|
||||
if pres_mtd:
|
||||
[mtd.setValue("tag.{}".format(k), v)
|
||||
[mtd.setValue("tag.{}".format(str(k)), str(v))
|
||||
for k, v in pres_mtd.items()]
|
||||
|
||||
return tag
|
||||
|
|
|
|||
|
|
@ -56,7 +56,15 @@ class IntegrateFtrackApi(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
|
||||
session = instance.context.data["ftrackSession"]
|
||||
if instance.context.data.get("ftrackTask"):
|
||||
if instance.data.get("ftrackTask"):
|
||||
task = instance.data["ftrackTask"]
|
||||
name = task
|
||||
parent = task["parent"]
|
||||
elif instance.data.get("ftrackEntity"):
|
||||
task = None
|
||||
name = instance.data.get("ftrackEntity")['name']
|
||||
parent = instance.data.get("ftrackEntity")
|
||||
elif instance.context.data.get("ftrackTask"):
|
||||
task = instance.context.data["ftrackTask"]
|
||||
name = task
|
||||
parent = task["parent"]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin):
|
|||
'write': 'img',
|
||||
'render': 'render',
|
||||
'nukescript': 'comp',
|
||||
'review': 'mov'}
|
||||
'review': 'mov',
|
||||
'plates': 'img'
|
||||
}
|
||||
|
||||
def process(self, instance):
|
||||
self.log.debug('instance {}'.format(instance))
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
def import_to_ftrack(self, input_data, parent=None):
|
||||
for entity_name in input_data:
|
||||
entity_data = input_data[entity_name]
|
||||
entity_type = entity_data['entity_type'].capitalize()
|
||||
entity_type = entity_data['entity_type']
|
||||
|
||||
if entity_type.lower() == 'project':
|
||||
query = 'Project where full_name is "{}"'.format(entity_name)
|
||||
|
|
@ -85,8 +85,9 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
'Missing custom attribute')
|
||||
|
||||
entity['custom_attributes'][key] = custom_attributes[key]
|
||||
|
||||
for instance in instances:
|
||||
instance.data['ftrackShotId'] = entity['id']
|
||||
instance.data['ftrackEntity'] = entity
|
||||
|
||||
self.session.commit()
|
||||
|
||||
|
|
@ -108,7 +109,7 @@ class IntegrateHierarchyToFtrack(pyblish.api.ContextPlugin):
|
|||
for task in tasks_to_create:
|
||||
self.create_task(
|
||||
name=task,
|
||||
task_type=task.capitalize(),
|
||||
task_type=task,
|
||||
parent=entity
|
||||
)
|
||||
self.session.commit()
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ class CleanUp(pyblish.api.InstancePlugin):
|
|||
order = pyblish.api.IntegratorOrder + 10
|
||||
label = "Clean Up"
|
||||
exclude_families = ["clip"]
|
||||
optional = True
|
||||
active = True
|
||||
|
||||
def process(self, instance):
|
||||
if [ef for ef in self.exclude_families
|
||||
|
|
|
|||
|
|
@ -12,13 +12,15 @@ class CollectAssumedDestination(pyblish.api.ContextPlugin):
|
|||
exclude_families = ["clip"]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
for instance in context:
|
||||
if [ef for ef in self.exclude_families
|
||||
if ef in instance.data["family"]]:
|
||||
self.log.info("Ignoring instance: {}".format(instance))
|
||||
return
|
||||
self.process_item(instance)
|
||||
|
||||
def process_item(self, instance):
|
||||
if [ef for ef in self.exclude_families
|
||||
if instance.data["family"] in ef]:
|
||||
return
|
||||
|
||||
self.create_destination_template(instance)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,21 @@ class CollectPresets(api.ContextPlugin):
|
|||
label = "Collect Presets"
|
||||
|
||||
def process(self, context):
|
||||
context.data["presets"] = config.get_presets()
|
||||
presets = config.get_presets()
|
||||
try:
|
||||
# try if it is not in projects custom directory
|
||||
# `{PYPE_PROJECT_CONFIGS}/[PROJECT_NAME]/init.json`
|
||||
# init.json define preset names to be used
|
||||
p_init = presets["init"]
|
||||
presets["colorspace"] = presets["colorspace"][p_init["colorspace"]]
|
||||
presets["dataflow"] = presets["dataflow"][p_init["dataflow"]]
|
||||
except KeyError:
|
||||
log.warning("No projects custom preset available...")
|
||||
presets["colorspace"] = presets["colorspace"]["default"]
|
||||
presets["dataflow"] = presets["dataflow"]["default"]
|
||||
log.info("Presets `colorspace` and `dataflow` loaded from `default`...")
|
||||
|
||||
context.data["presets"] = presets
|
||||
|
||||
self.log.info(context.data["presets"])
|
||||
return
|
||||
|
|
|
|||
|
|
@ -13,14 +13,14 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
|
||||
def process(self, instance):
|
||||
|
||||
self.create_destination_template(instance)
|
||||
anatomy = instance.context.data['anatomy']
|
||||
|
||||
self.create_destination_template(instance, anatomy)
|
||||
|
||||
template_data = instance.data["assumedTemplateData"]
|
||||
# template = instance.data["template"]
|
||||
|
||||
anatomy = instance.context.data['anatomy']
|
||||
# self.log.info(anatomy.templates)
|
||||
anatomy_filled = anatomy.format(template_data)
|
||||
|
||||
# self.log.info(anatomy_filled)
|
||||
mock_template = anatomy_filled["publish"]["path"]
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
"resources")
|
||||
|
||||
# Clean the path
|
||||
mock_destination = os.path.abspath(os.path.normpath(mock_destination))
|
||||
mock_destination = os.path.abspath(os.path.normpath(mock_destination)).replace("\\", "/")
|
||||
|
||||
# Define resource destination and transfers
|
||||
resources = instance.data.get("resources", list())
|
||||
|
|
@ -38,7 +38,7 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
for resource in resources:
|
||||
|
||||
# Add destination to the resource
|
||||
source_filename = os.path.basename(resource["source"])
|
||||
source_filename = os.path.basename(resource["source"]).replace("\\", "/")
|
||||
destination = os.path.join(mock_destination, source_filename)
|
||||
|
||||
# Force forward slashes to fix issue with software unable
|
||||
|
|
@ -53,13 +53,13 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
files = resource['files']
|
||||
for fsrc in files:
|
||||
fname = os.path.basename(fsrc)
|
||||
fdest = os.path.join(mock_destination, fname)
|
||||
fdest = os.path.join(mock_destination, fname).replace("\\", "/")
|
||||
transfers.append([fsrc, fdest])
|
||||
|
||||
instance.data["resources"] = resources
|
||||
instance.data["transfers"] = transfers
|
||||
|
||||
def create_destination_template(self, instance):
|
||||
def create_destination_template(self, instance, anatomy):
|
||||
"""Create a filepath based on the current data available
|
||||
|
||||
Example template:
|
||||
|
|
@ -77,12 +77,13 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
self.log.info(subset_name)
|
||||
asset_name = instance.data["asset"]
|
||||
project_name = api.Session["AVALON_PROJECT"]
|
||||
a_template = anatomy.templates
|
||||
|
||||
project = io.find_one({"type": "project",
|
||||
"name": project_name},
|
||||
projection={"config": True, "data": True})
|
||||
|
||||
template = project["config"]["template"]["publish"]
|
||||
template = a_template['publish']['path']
|
||||
# anatomy = instance.context.data['anatomy']
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
|
|
@ -112,10 +113,12 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
if instance.data.get('version'):
|
||||
version_number = int(instance.data.get('version'))
|
||||
|
||||
padding = int(a_template['render']['padding'])
|
||||
|
||||
hierarchy = asset['data']['parents']
|
||||
if hierarchy:
|
||||
# hierarchy = os.path.sep.join(hierarchy)
|
||||
hierarchy = os.path.join(*hierarchy)
|
||||
hierarchy = "/".join(hierarchy)
|
||||
|
||||
template_data = {"root": api.Session["AVALON_PROJECTS"],
|
||||
"project": {"name": project_name,
|
||||
|
|
@ -124,6 +127,7 @@ class IntegrateAssumedDestination(pyblish.api.InstancePlugin):
|
|||
"family": instance.data['family'],
|
||||
"asset": asset_name,
|
||||
"subset": subset_name,
|
||||
"frame": ('#' * padding),
|
||||
"version": version_number,
|
||||
"hierarchy": hierarchy,
|
||||
"representation": "TEMP"}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
"review",
|
||||
"nukescript",
|
||||
"render",
|
||||
"write"
|
||||
"write",
|
||||
"plates"
|
||||
]
|
||||
exclude_families = ["clip"]
|
||||
|
||||
|
|
@ -80,6 +81,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
# Required environment variables
|
||||
PROJECT = api.Session["AVALON_PROJECT"]
|
||||
ASSET = instance.data.get("asset") or api.Session["AVALON_ASSET"]
|
||||
TASK = instance.data.get("task") or api.Session["AVALON_TASK"]
|
||||
LOCATION = api.Session["AVALON_LOCATION"]
|
||||
|
||||
context = instance.context
|
||||
|
|
@ -159,6 +161,12 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
self.log.debug("Next version: v{0:03d}".format(next_version))
|
||||
|
||||
version_data = self.create_version_data(context, instance)
|
||||
|
||||
version_data_instance = instance.data.get('versionData')
|
||||
|
||||
if version_data_instance:
|
||||
version_data.update(version_data_instance)
|
||||
|
||||
version = self.create_version(subset=subset,
|
||||
version_number=next_version,
|
||||
locations=[LOCATION],
|
||||
|
|
@ -192,7 +200,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
"project": {"name": PROJECT,
|
||||
"code": project['data']['code']},
|
||||
"silo": asset['silo'],
|
||||
"task": api.Session["AVALON_TASK"],
|
||||
"task": TASK,
|
||||
"asset": ASSET,
|
||||
"family": instance.data['family'],
|
||||
"subset": subset["name"],
|
||||
|
|
@ -209,7 +217,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
if 'transfers' not in instance.data:
|
||||
instance.data['transfers'] = []
|
||||
|
||||
for idx, repre in enumerate(instance.data["representations"]):
|
||||
for idx, repre in enumerate(repres):
|
||||
|
||||
# Collection
|
||||
# _______
|
||||
|
|
@ -226,7 +234,9 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
stagingdir = repre['stagingDir']
|
||||
if repre.get('anatomy_template'):
|
||||
template_name = repre['anatomy_template']
|
||||
template = anatomy.templates[template_name]["path"]
|
||||
template = os.path.normpath(
|
||||
anatomy.templates[template_name]["path"])
|
||||
|
||||
|
||||
if isinstance(files, list):
|
||||
src_collections, remainder = clique.assemble(files)
|
||||
|
|
@ -244,7 +254,9 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
"{padding}") % i
|
||||
anatomy_filled = anatomy.format(template_data)
|
||||
test_dest_files.append(
|
||||
anatomy_filled[template_name]["path"])
|
||||
os.path.normpath(
|
||||
anatomy_filled[template_name]["path"])
|
||||
)
|
||||
self.log.debug(
|
||||
"test_dest_files: {}".format(str(test_dest_files)))
|
||||
|
||||
|
|
@ -253,7 +265,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
dst_head = dst_collection.format("{head}")
|
||||
dst_tail = dst_collection.format("{tail}")
|
||||
|
||||
instance.data["representations"][idx]['published_path'] = dst_collection.format()
|
||||
repres[idx]['published_path'] = dst_collection.format()
|
||||
|
||||
for i in src_collection.indexes:
|
||||
src_padding = src_collection.format("{padding}") % i
|
||||
|
|
@ -264,10 +276,14 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
dst = "{0}{1}{2}".format(dst_head, dst_padding, dst_tail)
|
||||
|
||||
src = os.path.join(stagingdir, src_file_name)
|
||||
# src = src_file_name
|
||||
self.log.debug("source: {}".format(src))
|
||||
instance.data["transfers"].append([src, dst])
|
||||
|
||||
# for imagesequence version data
|
||||
hashes = '#' * len(dst_padding)
|
||||
dst = "{0}{1}{2}".format(dst_head, hashes, dst_tail)
|
||||
|
||||
|
||||
else:
|
||||
# Single file
|
||||
# _______
|
||||
|
|
@ -292,7 +308,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
dst = anatomy_filled[template_name]["path"]
|
||||
|
||||
instance.data["transfers"].append([src, dst])
|
||||
instance.data["representations"][idx]['published_path'] = dst
|
||||
repres[idx]['published_path'] = dst
|
||||
|
||||
representation = {
|
||||
"schema": "pype:representation-2.0",
|
||||
|
|
@ -308,7 +324,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
"root": root,
|
||||
"project": {"name": PROJECT,
|
||||
"code": project['data']['code']},
|
||||
'task': api.Session["AVALON_TASK"],
|
||||
'task': TASK,
|
||||
"silo": asset['silo'],
|
||||
"asset": ASSET,
|
||||
"family": instance.data['family'],
|
||||
|
|
@ -323,9 +339,10 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
instance.data['destination_list'] = destination_list
|
||||
representations.append(representation)
|
||||
|
||||
self.log.info("Registering {} items".format(len(representations)))
|
||||
|
||||
io.insert_many(representations)
|
||||
self.log.debug("Representation: {}".format(representations))
|
||||
self.log.info("Registered {} items".format(len(representations)))
|
||||
|
||||
|
||||
def integrate(self, instance):
|
||||
"""Move the files
|
||||
|
|
@ -339,7 +356,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
transfers = instance.data.get("transfers", list())
|
||||
|
||||
for src, dest in transfers:
|
||||
self.log.info("Copying file .. {} -> {}".format(src, dest))
|
||||
self.log.debug("Copying file .. {} -> {}".format(src, dest))
|
||||
self.copy_file(src, dest)
|
||||
|
||||
# Produce hardlinked copies
|
||||
|
|
@ -349,7 +366,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin):
|
|||
# to ensure publishes remain safe and non-edited.
|
||||
hardlinks = instance.data.get("hardlinks", list())
|
||||
for src, dest in hardlinks:
|
||||
self.log.info("Hardlinking file .. {} -> {}".format(src, dest))
|
||||
self.log.debug("Hardlinking file .. {} -> {}".format(src, dest))
|
||||
self.hardlink_file(src, dest)
|
||||
|
||||
def copy_file(self, src, dst):
|
||||
|
|
|
|||
|
|
@ -75,8 +75,8 @@ def loader_shift(node, frame, relative=True):
|
|||
class LoadSequence(api.Loader):
|
||||
"""Load image sequence into Nuke"""
|
||||
|
||||
families = ["write", "source"]
|
||||
representations = ["exr", "dpx"]
|
||||
families = ["write", "source", "plates"]
|
||||
representations = ["exr", "dpx"]
|
||||
|
||||
label = "Load sequence"
|
||||
order = -10
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
from pyblish import api
|
||||
|
||||
|
||||
class CollectClipSubsets(api.InstancePlugin):
|
||||
"""Collect Subsets from selected Clips, Tags, Preset."""
|
||||
|
||||
order = api.CollectorOrder + 0.01
|
||||
label = "Collect Subsets"
|
||||
hosts = ["nukestudio"]
|
||||
families = ['clip']
|
||||
|
||||
def process(self, instance):
|
||||
tags = instance.data.get('tags', None)
|
||||
presets = instance.context.data['presets'][
|
||||
instance.context.data['host']]
|
||||
if tags:
|
||||
self.log.info(tags)
|
||||
|
||||
if presets:
|
||||
self.log.info(presets)
|
||||
|
||||
# get presets and tags
|
||||
# iterate tags and get task family
|
||||
# iterate tags and get host family
|
||||
# iterate tags and get handles family
|
||||
|
||||
instance = instance.context.create_instance(instance_name)
|
||||
|
||||
instance.data.update({
|
||||
"subset": subset_name,
|
||||
"stagingDir": staging_dir,
|
||||
"task": task,
|
||||
"representation": ext[1:],
|
||||
"host": host,
|
||||
"asset": asset_name,
|
||||
"label": label,
|
||||
"name": name,
|
||||
# "hierarchy": hierarchy,
|
||||
# "parents": parents,
|
||||
"family": family,
|
||||
"families": [families, 'ftrack'],
|
||||
"publish": True,
|
||||
# "files": files_list
|
||||
})
|
||||
instances.append(instance)
|
||||
|
|
@ -7,7 +7,7 @@ class ExtractTasks(api.InstancePlugin):
|
|||
order = api.ExtractorOrder
|
||||
label = "Tasks"
|
||||
hosts = ["nukestudio"]
|
||||
families = ["trackItem.task"]
|
||||
families = ["clip"]
|
||||
optional = True
|
||||
|
||||
def filelink(self, src, dst):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
- tags get tasks
|
||||
|
||||
- collect_subset(instance):
|
||||
- gets presets for subset by tasks
|
||||
- creates instances for comp .nk, plates (main instance converted to plates)
|
||||
- add families:
|
||||
- .nk compositing script [workfile, ftrack]
|
||||
- plates [plates]
|
||||
- audio [audio]
|
||||
|
||||
- extract_submit_frameserver(instance)
|
||||
- families [plates]
|
||||
- adds .nk script created only for encoding (plates write) no color correction
|
||||
- adds .nk script created only for encoding (mov write)
|
||||
- add .nk script created only for encoding (jpg, thumbnail)
|
||||
- _______
|
||||
- from hiero.ui.nuke_bridge import FnNsFrameServer
|
||||
- FnNsFrameServer.renderFrames(nks, "1-10", "Write_exr", ["main"])
|
||||
- dict(script(str), framerange(str), writeNode(str), views(list))
|
||||
|
||||
# next step ########################################################
|
||||
- submit_exporting_task(instance)
|
||||
- families [workfile]
|
||||
- create compositing scripts
|
||||
- create inventory containers for Reads
|
||||
- create publishable write nodes
|
||||
|
|
@ -10,9 +10,9 @@ class CollectClips(api.ContextPlugin):
|
|||
|
||||
def process(self, context):
|
||||
projectdata = context.data["projectData"]
|
||||
version = context.data.get("version", "001")
|
||||
data = {}
|
||||
for item in context.data.get("selection", []):
|
||||
self.log.debug("__ item: {}".format(item))
|
||||
# Skip audio track items
|
||||
# Try/Except is to handle items types, like EffectTrackItem
|
||||
try:
|
||||
|
|
@ -22,8 +22,11 @@ class CollectClips(api.ContextPlugin):
|
|||
except:
|
||||
continue
|
||||
|
||||
data[item.name()] = {
|
||||
track = item.parent()
|
||||
instance_name = "{0}_{1}".format(track.name(), item.name())
|
||||
data[instance_name] = {
|
||||
"item": item,
|
||||
"track": track.name(),
|
||||
"startFrame": int(item.timelineIn()),
|
||||
"endFrame": int(item.timelineOut())
|
||||
}
|
||||
|
|
@ -32,11 +35,15 @@ class CollectClips(api.ContextPlugin):
|
|||
family = "clip"
|
||||
context.create_instance(
|
||||
name=key,
|
||||
subset="{0}{1}".format(family, 'Default'),
|
||||
asset=value["item"].name(),
|
||||
item=value["item"],
|
||||
family=family,
|
||||
families=[],
|
||||
startFrame=value["startFrame"],
|
||||
endFrame=value["endFrame"],
|
||||
handles=projectdata['handles']
|
||||
handles=projectdata['handles'],
|
||||
handleStart=0,
|
||||
handleEnd=0,
|
||||
version=version,
|
||||
track=value["track"]
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import pyblish.api
|
||||
|
||||
import pype.api as pype
|
||||
|
||||
class CollectCurrentFile(pyblish.api.ContextPlugin):
|
||||
"""Inject the current working file into context"""
|
||||
|
|
@ -10,5 +10,7 @@ class CollectCurrentFile(pyblish.api.ContextPlugin):
|
|||
"""Todo, inject the current working file"""
|
||||
|
||||
project = context.data('activeProject')
|
||||
context.set_data('currentFile', value=project.path())
|
||||
context.data["currentFile"] = path = project.path()
|
||||
context.data["version"] = pype.get_version_from_path(path)
|
||||
self.log.info("currentFile: {}".format(context.data["currentFile"]))
|
||||
self.log.info("version: {}".format(context.data["version"]))
|
||||
|
|
|
|||
|
|
@ -35,18 +35,12 @@ class CollectClipHandles(api.InstancePlugin):
|
|||
t_args = json.loads(t_args.replace("'", "\""))
|
||||
# add in start
|
||||
if 'start' in t_args['where']:
|
||||
hs = instance.data.get('handle_start')
|
||||
if not hs:
|
||||
instance.data['handle_start'] = 0
|
||||
instance.data['handle_start'] += t_value
|
||||
instance.data["handleStart"] += t_value
|
||||
self.log.info("Collected Handle Start: `{}`".format(
|
||||
instance.data['handle_start']))
|
||||
instance.data["handleStart"]))
|
||||
|
||||
# add in end
|
||||
if 'end' in t_args['where']:
|
||||
hs = instance.data.get('handle_end')
|
||||
if not hs:
|
||||
instance.data['handle_end'] = 0
|
||||
instance.data['handle_end'] += t_value
|
||||
instance.data["handleEnd"] += t_value
|
||||
self.log.info("Collected Handle End: `{}`".format(
|
||||
instance.data['handle_end']))
|
||||
instance.data["handleEnd"]))
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
clip = instance.data["item"]
|
||||
asset = instance.data.get("asset")
|
||||
|
||||
# create asset_names conversion table
|
||||
if not context.data.get("assetsSharedHierarchy"):
|
||||
context.data["assetsSharedHierarchy"] = dict()
|
||||
|
||||
# build data for inner nukestudio project property
|
||||
data = {
|
||||
"sequence": context.data['activeSequence'].name().replace(' ', '_'),
|
||||
|
|
@ -65,17 +69,23 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
|
||||
# if shot in template then remove it
|
||||
if "shot" in template.lower():
|
||||
instance.data["asset"] = [t for t in template.split('/')][-1]
|
||||
instance.data["asset"] = [
|
||||
t for t in template.split('/')][-1]
|
||||
template = "/".join([t for t in template.split('/')][0:-1])
|
||||
|
||||
# take template from Tag.note and break it into parts
|
||||
template_split = template.split("/")
|
||||
patern = re.compile(r"\{([a-z]*?)\}")
|
||||
par_split = [patern.findall(t)[0]
|
||||
par_split = [patern.findall(t)
|
||||
for t in template.split("/")]
|
||||
|
||||
# format all {} in two layers
|
||||
for k, v in t_metadata.items():
|
||||
new_k = k.split(".")[1]
|
||||
|
||||
# ignore all help strings
|
||||
if 'help' in k:
|
||||
continue
|
||||
# self.log.info("__ new_k: `{}`".format(new_k))
|
||||
try:
|
||||
# first try all data and context data to
|
||||
|
|
@ -91,7 +101,8 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
|
||||
# if any is matching then convert to entity_types
|
||||
if p_match_i:
|
||||
parent = self.convert_to_entity(new_k, new_v)
|
||||
parent = self.convert_to_entity(
|
||||
new_k, template_split[p_match_i[0]])
|
||||
parents.insert(p_match_i[0], parent)
|
||||
except Exception:
|
||||
d_metadata[new_k] = v
|
||||
|
|
@ -102,6 +113,10 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
|
||||
# lastly fill those individual properties itno
|
||||
# format the string with collected data
|
||||
parents = [{"entityName": p["entityName"].format(
|
||||
**d_metadata), "entityType": p["entityType"]}
|
||||
for p in parents]
|
||||
|
||||
hierarchy = template.format(
|
||||
**d_metadata)
|
||||
|
||||
|
|
@ -111,12 +126,17 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
assert not hd, "Only one Hierarchy Tag is \
|
||||
allowed. Clip: `{}`".format(asset)
|
||||
|
||||
assetsSharedHierarchy = {
|
||||
asset: {
|
||||
"asset": instance.data["asset"],
|
||||
"hierarchy": hierarchy,
|
||||
"parents": parents
|
||||
}}
|
||||
# add formated hierarchy path into instance data
|
||||
instance.data["hierarchy"] = hierarchy
|
||||
instance.data["parents"] = parents
|
||||
self.log.debug("__ hierarchy.format: {}".format(hierarchy))
|
||||
self.log.debug("__ parents: {}".format(parents))
|
||||
self.log.debug("__ d_metadata: {}".format(d_metadata))
|
||||
context.data["assetsSharedHierarchy"].update(
|
||||
assetsSharedHierarchy)
|
||||
|
||||
|
||||
class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
||||
|
|
@ -132,21 +152,36 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
if key in new_dict and isinstance(ex_dict[key], dict):
|
||||
new_dict[key] = self.update_dict(ex_dict[key], new_dict[key])
|
||||
else:
|
||||
new_dict[key] = ex_dict[key]
|
||||
if ex_dict.get(key) and new_dict.get(key):
|
||||
continue
|
||||
else:
|
||||
new_dict[key] = ex_dict[key]
|
||||
|
||||
return new_dict
|
||||
|
||||
def process(self, context):
|
||||
instances = context[:]
|
||||
# create hierarchyContext attr if context has none
|
||||
self.log.debug("__ instances: {}".format(context[:]))
|
||||
|
||||
temp_context = {}
|
||||
for instance in instances:
|
||||
if 'projectfile' in instance.data.get('family', ''):
|
||||
continue
|
||||
|
||||
in_info = {}
|
||||
name = instance.data["asset"]
|
||||
|
||||
# inject assetsSharedHierarchy to other plates types
|
||||
assets_shared = context.data.get("assetsSharedHierarchy")
|
||||
|
||||
if assets_shared:
|
||||
s_asset_data = assets_shared.get(name)
|
||||
if s_asset_data:
|
||||
name = instance.data["asset"] = s_asset_data["asset"]
|
||||
instance.data["parents"] = s_asset_data["parents"]
|
||||
instance.data["hierarchy"] = s_asset_data["hierarchy"]
|
||||
|
||||
|
||||
in_info = {}
|
||||
# suppose that all instances are Shots
|
||||
in_info['entity_type'] = 'Shot'
|
||||
|
||||
|
|
@ -172,7 +207,6 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
actual = next_dict
|
||||
|
||||
temp_context = self.update_dict(temp_context, actual)
|
||||
self.log.debug(temp_context)
|
||||
|
||||
# TODO: 100% sure way of get project! Will be Name or Code?
|
||||
project_name = avalon.Session["AVALON_PROJECT"]
|
||||
|
|
|
|||
194
pype/plugins/nukestudio/publish/collect_subsets.py
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
from pyblish import api
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
class CollectClipSubsets(api.InstancePlugin):
|
||||
"""Collect Subsets from selected Clips, Tags, Preset."""
|
||||
|
||||
order = api.CollectorOrder + 0.102
|
||||
label = "Collect Subsets"
|
||||
hosts = ["nukestudio"]
|
||||
families = ['clip']
|
||||
|
||||
def process(self, instance):
|
||||
context = instance.context
|
||||
|
||||
asset_name = instance.data["asset"]
|
||||
|
||||
# get all subsets from tags and match them with nks_presets >
|
||||
# > looks to rules for tasks, subsets, representations
|
||||
subsets_collection = self.get_subsets_from_presets(instance)
|
||||
|
||||
# iterate trough subsets and create instances
|
||||
for subset, attrs in subsets_collection.items():
|
||||
self.log.info((subset, attrs))
|
||||
# create families
|
||||
item = instance.data["item"]
|
||||
family = instance.data["family"]
|
||||
families = attrs["families"] + [str(subset)]
|
||||
task = attrs["task"]
|
||||
subset = "{0}{1}".format(
|
||||
subset,
|
||||
instance.data.get("subsetType") or "Default")
|
||||
instance_name = "{0}_{1}_{2}".format(asset_name, task, subset)
|
||||
self.log.info("Creating instance with name: {}".format(
|
||||
instance_name))
|
||||
|
||||
# get handles
|
||||
handles = int(instance.data["handles"])
|
||||
handle_start = int(instance.data["handleStart"] + handles)
|
||||
handle_end = int(instance.data["handleEnd"] + handles)
|
||||
|
||||
# get timeline frames
|
||||
timeline_in = int(item.timelineIn())
|
||||
timeline_out = int(item.timelineOut())
|
||||
|
||||
# frame-ranges with handles
|
||||
timeline_frame_start = timeline_in - handle_start
|
||||
timeline_frame_end = timeline_out + handle_end
|
||||
|
||||
# creating comp frame range
|
||||
frame_start = instance.data["frameStart"] - handle_start
|
||||
frame_end = frame_start + \
|
||||
(timeline_frame_end - timeline_frame_start)
|
||||
|
||||
# get sequence from context, and fps
|
||||
sequence = context.data["activeSequence"]
|
||||
fps = int(str(sequence.framerate()))
|
||||
|
||||
context.create_instance(
|
||||
name=instance_name,
|
||||
subset=subset,
|
||||
asset=asset_name,
|
||||
track=instance.data.get("track"),
|
||||
item=item,
|
||||
task=task,
|
||||
family=family,
|
||||
families=families,
|
||||
frameStart=frame_start,
|
||||
startFrame=frame_start,
|
||||
endFrame=frame_end,
|
||||
timelineIn=timeline_in,
|
||||
timelineOut=timeline_out,
|
||||
timelineInHandles=timeline_frame_start,
|
||||
timelineOutHandles=timeline_frame_end,
|
||||
fps=fps,
|
||||
handles=instance.data["handles"],
|
||||
handleStart=handle_start,
|
||||
handleEnd=handle_end,
|
||||
attributes=attrs,
|
||||
version=instance.data["version"],
|
||||
hierarchy=instance.data.get("hierarchy", None),
|
||||
parents=instance.data.get("parents", None),
|
||||
publish=True
|
||||
)
|
||||
|
||||
# removing original instance
|
||||
context.remove(instance)
|
||||
|
||||
def get_subsets_from_presets(self, instance):
|
||||
|
||||
family = instance.data["family"]
|
||||
# get presets and tags
|
||||
tag_tasks = instance.data["tasks"]
|
||||
presets = instance.context.data['presets']
|
||||
nks_presets = presets[instance.context.data['host']]
|
||||
family_default_preset = nks_presets["asset_default"].get(family)
|
||||
|
||||
if family_default_preset:
|
||||
frame_start = family_default_preset.get("fstart", 1)
|
||||
instance.data["frameStart"] = int(frame_start)
|
||||
|
||||
# get specific presets
|
||||
pr_host_tasks = deepcopy(
|
||||
nks_presets["rules_tasks"]).get("hostTasks", None)
|
||||
pr_host_subsets = deepcopy(
|
||||
nks_presets["rules_tasks"]).get("hostSubsets", None)
|
||||
|
||||
subsets_collect = dict()
|
||||
# iterate tags and collect subset properities from presets
|
||||
for task in tag_tasks:
|
||||
try:
|
||||
# get host for task
|
||||
host = None
|
||||
host = [h for h, tasks in pr_host_tasks.items()
|
||||
if task in tasks][0]
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
try:
|
||||
# get subsets for task
|
||||
subsets = None
|
||||
subsets = pr_host_subsets[host]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not subsets:
|
||||
continue
|
||||
|
||||
# get subsets for task
|
||||
for sub in subsets:
|
||||
# get specific presets
|
||||
pr_subsets = deepcopy(nks_presets["rules_subsets"])
|
||||
pr_representations = deepcopy(
|
||||
nks_presets["rules_representations"])
|
||||
|
||||
# initialise collection dictionary
|
||||
subs_data = dict()
|
||||
|
||||
# gets subset properities
|
||||
subs_data[sub] = None
|
||||
subs_data[sub] = pr_subsets.get(sub, None)
|
||||
|
||||
# gets representation if in keys
|
||||
if subs_data[sub] and (
|
||||
"representation" in subs_data[sub].keys()
|
||||
):
|
||||
repr_name = subs_data[sub]["representation"]
|
||||
|
||||
# owerwrite representation key with values from preset
|
||||
subs_data[sub]["representation"] = pr_representations[
|
||||
repr_name
|
||||
]
|
||||
subs_data[sub]["representation"]["name"] = repr_name
|
||||
|
||||
# gets nodes and presets data if in keys
|
||||
# gets nodes if any
|
||||
if subs_data[sub] and (
|
||||
"nodes" in subs_data[sub].keys()
|
||||
):
|
||||
# iterate trough each node
|
||||
for k in subs_data[sub]["nodes"]:
|
||||
pr_node = k
|
||||
pr_family = subs_data[sub]["nodes"][k]["family"]
|
||||
|
||||
# create attribute dict for later filling
|
||||
subs_data[sub]["nodes"][k]["attributes"] = dict()
|
||||
|
||||
# iterate presets for the node
|
||||
for p, path in subs_data[sub]["nodes"][k][
|
||||
"presets"].items():
|
||||
|
||||
# adds node type and family for preset path
|
||||
nPath = path + [pr_node, pr_family]
|
||||
|
||||
# create basic iternode to be wolked trough until
|
||||
# found presets at the end
|
||||
iternode = presets[p]
|
||||
for part in nPath:
|
||||
iternode = iternode[part]
|
||||
|
||||
iternode = {k: v for k, v in iternode.items()
|
||||
if not k.startswith("_")}
|
||||
# adds found preset to attributes of the node
|
||||
subs_data[sub]["nodes"][k][
|
||||
"attributes"].update(iternode)
|
||||
|
||||
# removes preset key
|
||||
subs_data[sub]["nodes"][k].pop("presets")
|
||||
|
||||
# add all into dictionary
|
||||
subs_data[sub]["task"] = task.lower()
|
||||
subsets_collect.update(subs_data)
|
||||
|
||||
return subsets_collect
|
||||
34
pype/plugins/nukestudio/publish/collect_tag_types.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from pyblish import api
|
||||
|
||||
|
||||
class CollectClipTagTypes(api.InstancePlugin):
|
||||
"""Collect Types from Tags of selected track items."""
|
||||
|
||||
order = api.CollectorOrder + 0.007
|
||||
label = "Collect Plate Type from Tag"
|
||||
hosts = ["nukestudio"]
|
||||
families = ['clip']
|
||||
|
||||
def process(self, instance):
|
||||
# gets tags
|
||||
tags = instance.data["tags"]
|
||||
|
||||
subset_names = list()
|
||||
for t in tags:
|
||||
t_metadata = dict(t["metadata"])
|
||||
t_family = t_metadata.get("tag.family", "")
|
||||
|
||||
# gets only task family tags and collect labels
|
||||
if "plate" in t_family:
|
||||
t_type = t_metadata.get("tag.type", "")
|
||||
t_order = t_metadata.get("tag.order", "")
|
||||
subset_type = "{0}{1}".format(
|
||||
t_type.capitalize(), t_order)
|
||||
subset_names.append(subset_type)
|
||||
|
||||
if subset_names:
|
||||
instance.data["subsetType"] = subset_names[0]
|
||||
|
||||
self.log.info("Collected Plate Types from Tags: `{}`".format(
|
||||
instance.data["subsetType"]))
|
||||
return
|
||||
62
pype/plugins/nukestudio/publish/extract_audio.py
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
from pyblish import api
|
||||
import pype
|
||||
|
||||
class ExtractAudioFile(pype.api.Extractor):
|
||||
"""Extracts audio subset file"""
|
||||
|
||||
order = api.ExtractorOrder
|
||||
label = "Extract Subset Audio"
|
||||
hosts = ["nukestudio"]
|
||||
families = ["clip", "audio"]
|
||||
match = api.Intersection
|
||||
optional = True
|
||||
active = False
|
||||
|
||||
def process(self, instance):
|
||||
import os
|
||||
|
||||
from hiero.exporters.FnExportUtil import writeSequenceAudioWithHandles
|
||||
|
||||
item = instance.data["item"]
|
||||
context = instance.context
|
||||
|
||||
self.log.debug("creating staging dir")
|
||||
self.staging_dir(instance)
|
||||
|
||||
staging_dir = instance.data["stagingDir"]
|
||||
|
||||
# get handles from context
|
||||
handles = instance.data["handles"]
|
||||
handle_start = instance.data["handleStart"] + handles
|
||||
handle_end = instance.data["handleEnd"] + handles
|
||||
|
||||
# get sequence from context
|
||||
sequence = context.data["activeSequence"]
|
||||
|
||||
# path to wav file
|
||||
audio_file = os.path.join(
|
||||
staging_dir, "{0}.wav".format(instance.data["subset"])
|
||||
)
|
||||
|
||||
# export audio to disk
|
||||
writeSequenceAudioWithHandles(
|
||||
audio_file,
|
||||
sequence,
|
||||
item.timelineIn(),
|
||||
item.timelineOut(),
|
||||
handle_start,
|
||||
handle_end
|
||||
)
|
||||
|
||||
# add to representations
|
||||
if not instance.data.get("representations"):
|
||||
instance.data["representations"] = list()
|
||||
|
||||
representation = {
|
||||
'files': [audio_file],
|
||||
'stagingDir': staging_dir,
|
||||
'name': "wav",
|
||||
'ext': ".wav"
|
||||
}
|
||||
|
||||
instance.data["representations"].append(representation)
|
||||
239
pype/plugins/nukestudio/publish/extract_plates.py
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
from pyblish import api
|
||||
import pype
|
||||
|
||||
|
||||
class ExtractPlates(pype.api.Extractor):
|
||||
"""Extracts plates"""
|
||||
|
||||
order = api.ExtractorOrder
|
||||
label = "Extract Plates"
|
||||
hosts = ["nukestudio"]
|
||||
families = ["plates"]
|
||||
|
||||
def process(self, instance):
|
||||
import os
|
||||
import hiero.core
|
||||
from hiero.ui.nuke_bridge import FnNsFrameServer
|
||||
|
||||
# add to representations
|
||||
if not instance.data.get("representations"):
|
||||
instance.data["representations"] = list()
|
||||
|
||||
repr_data = dict()
|
||||
context = instance.context
|
||||
anatomy = context.data.get("anatomy", None)
|
||||
padding = int(anatomy.templates['render']['padding'])
|
||||
|
||||
name = instance.data["subset"]
|
||||
asset = instance.data["asset"]
|
||||
track = instance.data["track"]
|
||||
family = instance.data["family"]
|
||||
families = instance.data["families"]
|
||||
attrs = instance.data["attributes"]
|
||||
version = instance.data["version"]
|
||||
|
||||
# staging dir creation
|
||||
self.log.debug("creating staging dir")
|
||||
self.staging_dir(instance)
|
||||
|
||||
staging_dir = instance.data['stagingDir']
|
||||
|
||||
Nuke_writer = hiero.core.nuke.ScriptWriter()
|
||||
|
||||
item = instance.data["item"]
|
||||
|
||||
# get handles
|
||||
handles = int(instance.data["handles"])
|
||||
handle_start = int(instance.data["handleStart"])
|
||||
handle_end = int(instance.data["handleEnd"])
|
||||
|
||||
# get timeline frames
|
||||
timeline_in = int(instance.data["timelineIn"])
|
||||
timeline_out = int(instance.data["timelineOut"])
|
||||
|
||||
# frame-ranges with handles
|
||||
timeline_frame_start = int(instance.data["timelineInHandles"])
|
||||
timeline_frame_end = int(instance.data["timelineOutHandles"])
|
||||
|
||||
# creating comp frame range
|
||||
frame_start = int(instance.data["startFrame"])
|
||||
frame_end = int(instance.data["endFrame"])
|
||||
|
||||
# get colorspace
|
||||
colorspace = instance.context.data["colorspace"]
|
||||
|
||||
# get sequence from context, and fps
|
||||
fps = int(instance.data["fps"])
|
||||
|
||||
# test output
|
||||
self.log.debug("__ handles: {}".format(handles))
|
||||
self.log.debug("__ handle_start: {}".format(handle_start))
|
||||
self.log.debug("__ handle_end: {}".format(handle_end))
|
||||
self.log.debug("__ timeline_in: {}".format(timeline_in))
|
||||
self.log.debug("__ timeline_out: {}".format(timeline_out))
|
||||
self.log.debug("__ timeline_frame_start: {}".format(
|
||||
timeline_frame_start))
|
||||
self.log.debug("__ timeline_frame_end: {}".format(timeline_frame_end))
|
||||
self.log.debug("__ frame_start: {}".format(frame_start))
|
||||
self.log.debug("__ frame_end: {}".format(frame_end))
|
||||
self.log.debug("__ colorspace: {}".format(colorspace))
|
||||
self.log.debug("__ track: {}".format(track))
|
||||
self.log.debug("__ fps: {}".format(fps))
|
||||
|
||||
# Generate Nuke script
|
||||
write_name = "Write_out"
|
||||
|
||||
# root node
|
||||
root_node = hiero.core.nuke.RootNode(
|
||||
frame_start,
|
||||
frame_end,
|
||||
fps=fps
|
||||
)
|
||||
|
||||
root_node.addProjectSettings(colorspace)
|
||||
|
||||
# create write node and link it to root node
|
||||
Nuke_writer.addNode(root_node)
|
||||
'''TrackItem.addToNukeScript(script=, firstFrame=None, additionalNodes=[], additionalNodesCallback=None, includeRetimes=False, retimeMethod=None, startHandle=None, endHandle=None, colourTransform=None, offset=0, nodeLabel=None, includeAnnotations=False, includeEffects=True, outputToSequenceFormat=False)'''
|
||||
item.addToNukeScript(
|
||||
script=Nuke_writer,
|
||||
firstFrame=frame_start,
|
||||
includeRetimes=attrs["includeRetimes"],
|
||||
retimeMethod=attrs["retimeMethod"],
|
||||
startHandle=handle_start,
|
||||
endHandle=handle_end,
|
||||
includeEffects=attrs["includeEffects"],
|
||||
includeAnnotations=attrs["includeAnnotations"]
|
||||
)
|
||||
|
||||
write_knobs = attrs["nodes"]["write"]["attributes"]
|
||||
|
||||
# TODO: take template from anatomy
|
||||
nukescript_file = "{asset}_{name}_v{version}.{ext}".format(
|
||||
asset=asset,
|
||||
name=name,
|
||||
version=version,
|
||||
ext="nk"
|
||||
)
|
||||
nukescript_path = os.path.join(
|
||||
staging_dir, nukescript_file
|
||||
)
|
||||
|
||||
# TODO: take template from anatomy
|
||||
output_file = "{asset}_{name}_v{version}.%0{padding}d.{ext}".format(
|
||||
asset=asset,
|
||||
name=name,
|
||||
version=version,
|
||||
padding=padding,
|
||||
ext=write_knobs["file_type"]
|
||||
)
|
||||
output_path = os.path.join(
|
||||
staging_dir, output_file
|
||||
)
|
||||
|
||||
write_node = hiero.core.nuke.WriteNode(output_path.replace("\\", "/"))
|
||||
write_node.setKnob("name", write_name)
|
||||
write_node.setKnob("file_type", write_knobs["file_type"])
|
||||
for knob, value in write_knobs.items():
|
||||
write_node.setKnob(knob, value)
|
||||
|
||||
Nuke_writer.addNode(write_node)
|
||||
|
||||
Nuke_writer.writeToDisk(nukescript_path)
|
||||
|
||||
# test prints
|
||||
self.log.debug("__ output_file: {}".format(output_file))
|
||||
self.log.debug("__ output_path: {}".format(output_path))
|
||||
self.log.debug("__ nukescript_file: {}".format(nukescript_file))
|
||||
self.log.debug("__ nukescript_path: {}".format(nukescript_path))
|
||||
self.log.debug("__ write_knobs: {}".format(write_knobs))
|
||||
self.log.debug("__ write_name: {}".format(write_name))
|
||||
self.log.debug("__ Nuke_writer: {}".format(Nuke_writer))
|
||||
|
||||
# create rendering arguments for FnNsFrameServer
|
||||
_args = [
|
||||
nukescript_path,
|
||||
"{}-{}".format(frame_start, frame_end),
|
||||
write_name,
|
||||
["main"]
|
||||
]
|
||||
|
||||
# add to data of representation
|
||||
repr_data.update({
|
||||
"handles": handles,
|
||||
"handleStart": handle_start,
|
||||
"handleEnd": handle_end,
|
||||
"timelineIn": timeline_in,
|
||||
"timelineOut": timeline_out,
|
||||
"timelineInHandles": timeline_frame_start,
|
||||
"timelineOutHandles": timeline_frame_end,
|
||||
"compFrameIn": frame_start,
|
||||
"compFrameOut": frame_end,
|
||||
"fps": fps,
|
||||
"colorspace": write_knobs["colorspace"],
|
||||
"nukeScriptFileName": nukescript_file,
|
||||
"nukeWriteFileName": output_file,
|
||||
"nukeWriteName": write_name,
|
||||
"FnNsFrameServer_renderFrames_args": str(_args),
|
||||
"family": family,
|
||||
"families": families,
|
||||
"asset": asset,
|
||||
"subset": name,
|
||||
"track": track,
|
||||
"version": int(version)
|
||||
})
|
||||
|
||||
# adding representation for nukescript
|
||||
nk_representation = {
|
||||
'files': nukescript_file,
|
||||
'stagingDir': staging_dir,
|
||||
'name': "nk",
|
||||
'ext': "nk",
|
||||
"data": repr_data
|
||||
}
|
||||
instance.data["representations"].append(nk_representation)
|
||||
|
||||
# adding representation for plates
|
||||
plates_representation = {
|
||||
'files': [output_file % i for i in range(
|
||||
frame_start, (frame_end + 1), 1)],
|
||||
'stagingDir': staging_dir,
|
||||
'name': write_knobs["file_type"],
|
||||
'ext': write_knobs["file_type"],
|
||||
"data": repr_data
|
||||
}
|
||||
instance.data["representations"].append(plates_representation)
|
||||
|
||||
# adding checking file to context for ExtractPlateCheck(context) plugin
|
||||
context.data["platesCheck"] = os.path.join(
|
||||
staging_dir, output_file % frame_end
|
||||
)
|
||||
|
||||
if not context.data.get("frameServerRenderQueue"):
|
||||
context.data["frameServerRenderQueue"] = list()
|
||||
|
||||
# add to render queue list
|
||||
context.data["frameServerRenderQueue"].append(_args)
|
||||
|
||||
# test prints
|
||||
self.log.debug("__ before family: {}".format(family))
|
||||
self.log.debug("__ before families: {}".format(families))
|
||||
|
||||
# this is just workaround because 'clip' family is filtered
|
||||
instance.data["family"] = families[-1]
|
||||
instance.data["families"].append(family)
|
||||
|
||||
# testing families
|
||||
family = instance.data["family"]
|
||||
families = instance.data["families"]
|
||||
|
||||
# test prints repr_data
|
||||
self.log.debug("__ repr_data: {}".format(repr_data))
|
||||
self.log.debug("__ nk_representation: {}".format(nk_representation))
|
||||
self.log.debug("__ plates_representation: {}".format(
|
||||
plates_representation))
|
||||
self.log.debug("__ after family: {}".format(family))
|
||||
self.log.debug("__ after families: {}".format(families))
|
||||
|
||||
# this will do FnNsFrameServer
|
||||
FnNsFrameServer.renderFrames(*_args)
|
||||
30
pype/plugins/nukestudio/publish/extract_plates_waiting.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from pyblish import api
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
class ExtractPlateCheck(api.ContextPlugin):
|
||||
"""Collect all Track items selection."""
|
||||
|
||||
order = api.ExtractorOrder + 0.01
|
||||
label = "Plates Export Waiting"
|
||||
hosts = ["nukestudio"]
|
||||
families = ["plates"]
|
||||
|
||||
def process(self, context):
|
||||
|
||||
plate_path = context.data.get("platesCheck", None)
|
||||
|
||||
self.log.info("Chacking plate: `{}`".format(plate_path))
|
||||
|
||||
if not plate_path:
|
||||
return
|
||||
|
||||
while not os.path.exists(plate_path):
|
||||
self.log.info("Waiting for plates to be rendered")
|
||||
time.sleep(5)
|
||||
|
||||
if os.path.isfile(plate_path):
|
||||
self.log.info("Plates were rendered: `{}`".format(plate_path))
|
||||
else:
|
||||
raise ValueError("%s isn't a file!" % plate_path)
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
from pyblish import api
|
||||
|
||||
|
||||
class ExtractReview(api.InstancePlugin):
|
||||
"""Extracts movie for review"""
|
||||
|
||||
order = api.ExtractorOrder
|
||||
label = "NukeStudio Review"
|
||||
optional = True
|
||||
hosts = ["nukestudio"]
|
||||
families = ["review"]
|
||||
|
||||
def process(self, instance):
|
||||
import os
|
||||
import time
|
||||
|
||||
import hiero.core
|
||||
from hiero.exporters.FnExportUtil import writeSequenceAudioWithHandles
|
||||
|
||||
nukeWriter = hiero.core.nuke.ScriptWriter()
|
||||
|
||||
item = instance.data["item"]
|
||||
|
||||
handles = instance.data["handles"]
|
||||
|
||||
sequence = item.parent().parent()
|
||||
|
||||
output_path = os.path.abspath(
|
||||
os.path.join(
|
||||
instance.context.data["currentFile"], "..", "workspace"
|
||||
)
|
||||
)
|
||||
|
||||
# Generate audio
|
||||
audio_file = os.path.join(
|
||||
output_path, "{0}.wav".format(instance.data["name"])
|
||||
)
|
||||
|
||||
writeSequenceAudioWithHandles(
|
||||
audio_file,
|
||||
sequence,
|
||||
item.timelineIn(),
|
||||
item.timelineOut(),
|
||||
handles,
|
||||
handles
|
||||
)
|
||||
|
||||
# Generate Nuke script
|
||||
root_node = hiero.core.nuke.RootNode(
|
||||
item.timelineIn() - handles,
|
||||
item.timelineOut() + handles,
|
||||
fps=sequence.framerate()
|
||||
)
|
||||
|
||||
root_node.addProjectSettings(instance.context.data["colorspace"])
|
||||
|
||||
nukeWriter.addNode(root_node)
|
||||
|
||||
item.addToNukeScript(
|
||||
script=nukeWriter,
|
||||
includeRetimes=True,
|
||||
retimeMethod="Frame",
|
||||
startHandle=handles,
|
||||
endHandle=handles
|
||||
)
|
||||
|
||||
movie_path = os.path.join(
|
||||
output_path, "{0}.mov".format(instance.data["name"])
|
||||
)
|
||||
write_node = hiero.core.nuke.WriteNode(movie_path.replace("\\", "/"))
|
||||
self.log.info("__ write_node: {0}".format(write_node))
|
||||
write_node.setKnob("file_type", "mov")
|
||||
write_node.setKnob("colorspace", instance.context.data["colorspace"]["lutSettingFloat"])
|
||||
write_node.setKnob("meta_codec", "ap4h")
|
||||
write_node.setKnob("mov64_codec", "ap4h")
|
||||
write_node.setKnob("mov64_bitrate", 400000)
|
||||
write_node.setKnob("mov64_bitrate_tolerance", 40000000)
|
||||
write_node.setKnob("mov64_quality_min", 2)
|
||||
write_node.setKnob("mov64_quality_max", 31)
|
||||
write_node.setKnob("mov64_gop_size", 12)
|
||||
write_node.setKnob("mov64_b_frames", 0)
|
||||
write_node.setKnob("raw", True )
|
||||
write_node.setKnob("mov64_audiofile", audio_file.replace("\\", "/"))
|
||||
write_node.setKnob("mov32_fps", sequence.framerate())
|
||||
nukeWriter.addNode(write_node)
|
||||
|
||||
nukescript_path = movie_path.replace(".mov", ".nk")
|
||||
nukeWriter.writeToDisk(nukescript_path)
|
||||
|
||||
process = hiero.core.nuke.executeNukeScript(
|
||||
nukescript_path,
|
||||
open(movie_path.replace(".mov", ".log"), "w")
|
||||
)
|
||||
|
||||
while process.poll() is None:
|
||||
time.sleep(0.5)
|
||||
|
||||
assert os.path.exists(movie_path), "Creating review failed."
|
||||
|
||||
instance.data["output_path"] = movie_path
|
||||
instance.data["review_family"] = "mov"
|
||||
BIN
setup/nukestudio/hiero_plugin_path/Icons/1_add_handles_end.png
Normal file
|
After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 23 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/2_add_handles.png
Normal file
|
After Width: | Height: | Size: 215 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 96 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/3_add_handles_start.png
Normal file
|
After Width: | Height: | Size: 194 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/4_2D.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 73 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/layers.psd
Normal file
BIN
setup/nukestudio/hiero_plugin_path/Icons/lense.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/lense1.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/z_layer_bg.png
Normal file
|
After Width: | Height: | Size: 87 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/z_layer_fg.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
setup/nukestudio/hiero_plugin_path/Icons/z_layer_main.png
Normal file
|
After Width: | Height: | Size: 62 KiB |