mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 13:24:54 +01:00
feat(sp): adding hierarchy and framerange colectors
This commit is contained in:
parent
123fb5ff86
commit
9af892ecee
7 changed files with 274 additions and 406 deletions
|
|
@ -12,7 +12,7 @@ class CollectClips(pyblish.api.InstancePlugin):
|
|||
"""Collect Clips instances from editorial's OTIO sequence"""
|
||||
|
||||
order = pyblish.api.CollectorOrder + 0.01
|
||||
label = "Collect Shots"
|
||||
label = "Collect Clips"
|
||||
hosts = ["standalonepublisher"]
|
||||
families = ["editorial"]
|
||||
|
||||
|
|
@ -40,8 +40,7 @@ class CollectClips(pyblish.api.InstancePlugin):
|
|||
asset_name = asset_entity["name"]
|
||||
self.log.debug(f"__ asset_entity: `{asset_entity}`")
|
||||
|
||||
# Project specific prefix naming. This needs to be replaced with some
|
||||
# options to be more flexible.
|
||||
# split selected context asset name
|
||||
asset_name = asset_name.split("_")[0]
|
||||
|
||||
instances = []
|
||||
|
|
@ -71,7 +70,6 @@ class CollectClips(pyblish.api.InstancePlugin):
|
|||
if clip.name is None:
|
||||
continue
|
||||
|
||||
# Hardcoded to expect a shot name of "[name].[extension]"
|
||||
clip_name = os.path.splitext(clip.name)[0].lower()
|
||||
name = f"{asset_name}_{clip_name}"
|
||||
|
||||
|
|
@ -109,122 +107,124 @@ class CollectClips(pyblish.api.InstancePlugin):
|
|||
"family": "clip",
|
||||
"families": ["review", "ftrack"],
|
||||
"ftrackFamily": "review",
|
||||
"representations": []
|
||||
"representations": [],
|
||||
"editorialVideoPath": instance.data[
|
||||
"editorialVideoPath"]
|
||||
})
|
||||
)
|
||||
#
|
||||
# def process_old(self, instance):
|
||||
# representation = instance.data["representations"][0]
|
||||
# file_path = os.path.join(
|
||||
# representation["stagingDir"], representation["files"]
|
||||
# )
|
||||
# instance.context.data["editorialPath"] = file_path
|
||||
#
|
||||
# extension = os.path.splitext(file_path)[1][1:]
|
||||
# kwargs = {}
|
||||
# if extension == "edl":
|
||||
# # EDL has no frame rate embedded so needs explicit frame rate else
|
||||
# # 24 is asssumed.
|
||||
# kwargs["rate"] = plib.get_asset()["data"]["fps"]
|
||||
#
|
||||
# timeline = otio.adapters.read_from_file(file_path, **kwargs)
|
||||
# tracks = timeline.each_child(
|
||||
# descended_from_type=otio.schema.track.Track
|
||||
# )
|
||||
# asset_entity = instance.context.data["assetEntity"]
|
||||
# asset_name = asset_entity["name"]
|
||||
#
|
||||
# # Ask user for sequence start. Usually 10:00:00:00.
|
||||
# sequence_start_frame = 900000
|
||||
#
|
||||
# # Project specific prefix naming. This needs to be replaced with some
|
||||
# # options to be more flexible.
|
||||
# asset_name = asset_name.split("_")[0]
|
||||
#
|
||||
# instances = []
|
||||
# for track in tracks:
|
||||
# track_start_frame = (
|
||||
# abs(track.source_range.start_time.value) - sequence_start_frame
|
||||
# )
|
||||
# for child in track.each_child():
|
||||
# # skip all generators like black ampty
|
||||
# if isinstance(
|
||||
# child.media_reference,
|
||||
# otio.schema.GeneratorReference):
|
||||
# continue
|
||||
#
|
||||
# # Transitions are ignored, because Clips have the full frame
|
||||
# # range.
|
||||
# if isinstance(child, otio.schema.transition.Transition):
|
||||
# continue
|
||||
#
|
||||
# if child.name is None:
|
||||
# continue
|
||||
#
|
||||
# # Hardcoded to expect a shot name of "[name].[extension]"
|
||||
# child_name = os.path.splitext(child.name)[0].lower()
|
||||
# name = f"{asset_name}_{child_name}"
|
||||
#
|
||||
# frame_start = track_start_frame
|
||||
# frame_start += child.range_in_parent().start_time.value
|
||||
# frame_end = track_start_frame
|
||||
# frame_end += child.range_in_parent().end_time_inclusive().value
|
||||
#
|
||||
# label = f"{name} (framerange: {frame_start}-{frame_end})"
|
||||
# instances.append(
|
||||
# instance.context.create_instance(**{
|
||||
# "name": name,
|
||||
# "label": label,
|
||||
# "frameStart": frame_start,
|
||||
# "frameEnd": frame_end,
|
||||
# "family": "shot",
|
||||
# "families": ["review", "ftrack"],
|
||||
# "ftrackFamily": "review",
|
||||
# "asset": name,
|
||||
# "subset": "shotMain",
|
||||
# "representations": [],
|
||||
# "source": file_path
|
||||
# })
|
||||
# )
|
||||
#
|
||||
# visual_hierarchy = [asset_entity]
|
||||
# while True:
|
||||
# visual_parent = io.find_one(
|
||||
# {"_id": visual_hierarchy[-1]["data"]["visualParent"]}
|
||||
# )
|
||||
# if visual_parent:
|
||||
# visual_hierarchy.append(visual_parent)
|
||||
# else:
|
||||
# visual_hierarchy.append(instance.context.data["projectEntity"])
|
||||
# break
|
||||
#
|
||||
# context_hierarchy = None
|
||||
# for entity in visual_hierarchy:
|
||||
# childs = {}
|
||||
# if context_hierarchy:
|
||||
# name = context_hierarchy.pop("name")
|
||||
# childs = {name: context_hierarchy}
|
||||
# else:
|
||||
# for instance in instances:
|
||||
# childs[instance.data["name"]] = {
|
||||
# "childs": {},
|
||||
# "entity_type": "Shot",
|
||||
# "custom_attributes": {
|
||||
# "frameStart": instance.data["frameStart"],
|
||||
# "frameEnd": instance.data["frameEnd"]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# context_hierarchy = {
|
||||
# "entity_type": entity["data"]["entityType"],
|
||||
# "childs": childs,
|
||||
# "name": entity["name"]
|
||||
# }
|
||||
#
|
||||
# name = context_hierarchy.pop("name")
|
||||
# context_hierarchy = {name: context_hierarchy}
|
||||
# instance.context.data["hierarchyContext"] = context_hierarchy
|
||||
# self.log.info(
|
||||
# "Hierarchy:\n" +
|
||||
# json_util.dumps(context_hierarchy, sort_keys=True, indent=4)
|
||||
# )
|
||||
|
||||
def process_old(self, instance):
|
||||
representation = instance.data["representations"][0]
|
||||
file_path = os.path.join(
|
||||
representation["stagingDir"], representation["files"]
|
||||
)
|
||||
instance.context.data["editorialPath"] = file_path
|
||||
|
||||
extension = os.path.splitext(file_path)[1][1:]
|
||||
kwargs = {}
|
||||
if extension == "edl":
|
||||
# EDL has no frame rate embedded so needs explicit frame rate else
|
||||
# 24 is asssumed.
|
||||
kwargs["rate"] = plib.get_asset()["data"]["fps"]
|
||||
|
||||
timeline = otio.adapters.read_from_file(file_path, **kwargs)
|
||||
tracks = timeline.each_child(
|
||||
descended_from_type=otio.schema.track.Track
|
||||
)
|
||||
asset_entity = instance.context.data["assetEntity"]
|
||||
asset_name = asset_entity["name"]
|
||||
|
||||
# Ask user for sequence start. Usually 10:00:00:00.
|
||||
sequence_start_frame = 900000
|
||||
|
||||
# Project specific prefix naming. This needs to be replaced with some
|
||||
# options to be more flexible.
|
||||
asset_name = asset_name.split("_")[0]
|
||||
|
||||
instances = []
|
||||
for track in tracks:
|
||||
track_start_frame = (
|
||||
abs(track.source_range.start_time.value) - sequence_start_frame
|
||||
)
|
||||
for child in track.each_child():
|
||||
# skip all generators like black ampty
|
||||
if isinstance(
|
||||
child.media_reference,
|
||||
otio.schema.GeneratorReference):
|
||||
continue
|
||||
|
||||
# Transitions are ignored, because Clips have the full frame
|
||||
# range.
|
||||
if isinstance(child, otio.schema.transition.Transition):
|
||||
continue
|
||||
|
||||
if child.name is None:
|
||||
continue
|
||||
|
||||
# Hardcoded to expect a shot name of "[name].[extension]"
|
||||
child_name = os.path.splitext(child.name)[0].lower()
|
||||
name = f"{asset_name}_{child_name}"
|
||||
|
||||
frame_start = track_start_frame
|
||||
frame_start += child.range_in_parent().start_time.value
|
||||
frame_end = track_start_frame
|
||||
frame_end += child.range_in_parent().end_time_inclusive().value
|
||||
|
||||
label = f"{name} (framerange: {frame_start}-{frame_end})"
|
||||
instances.append(
|
||||
instance.context.create_instance(**{
|
||||
"name": name,
|
||||
"label": label,
|
||||
"frameStart": frame_start,
|
||||
"frameEnd": frame_end,
|
||||
"family": "shot",
|
||||
"families": ["review", "ftrack"],
|
||||
"ftrackFamily": "review",
|
||||
"asset": name,
|
||||
"subset": "shotMain",
|
||||
"representations": [],
|
||||
"source": file_path
|
||||
})
|
||||
)
|
||||
|
||||
visual_hierarchy = [asset_entity]
|
||||
while True:
|
||||
visual_parent = io.find_one(
|
||||
{"_id": visual_hierarchy[-1]["data"]["visualParent"]}
|
||||
)
|
||||
if visual_parent:
|
||||
visual_hierarchy.append(visual_parent)
|
||||
else:
|
||||
visual_hierarchy.append(instance.context.data["projectEntity"])
|
||||
break
|
||||
|
||||
context_hierarchy = None
|
||||
for entity in visual_hierarchy:
|
||||
childs = {}
|
||||
if context_hierarchy:
|
||||
name = context_hierarchy.pop("name")
|
||||
childs = {name: context_hierarchy}
|
||||
else:
|
||||
for instance in instances:
|
||||
childs[instance.data["name"]] = {
|
||||
"childs": {},
|
||||
"entity_type": "Shot",
|
||||
"custom_attributes": {
|
||||
"frameStart": instance.data["frameStart"],
|
||||
"frameEnd": instance.data["frameEnd"]
|
||||
}
|
||||
}
|
||||
|
||||
context_hierarchy = {
|
||||
"entity_type": entity["data"]["entityType"],
|
||||
"childs": childs,
|
||||
"name": entity["name"]
|
||||
}
|
||||
|
||||
name = context_hierarchy.pop("name")
|
||||
context_hierarchy = {name: context_hierarchy}
|
||||
instance.context.data["hierarchyContext"] = context_hierarchy
|
||||
self.log.info(
|
||||
"Hierarchy:\n" +
|
||||
json_util.dumps(context_hierarchy, sort_keys=True, indent=4)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -37,40 +37,40 @@ class CollectEditorial(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
self.log.debug(f"__ instance: `{instance}`")
|
||||
# get representation with editorial file
|
||||
representation = instance.data["representations"][0]
|
||||
|
||||
# make editorial sequence file path
|
||||
staging_dir = representation["stagingDir"]
|
||||
file_path = os.path.join(
|
||||
staging_dir, representation["files"]
|
||||
)
|
||||
|
||||
# get video file path
|
||||
video_path = None
|
||||
basename = os.path.splitext(os.path.basename(file_path))[0]
|
||||
for f in os.listdir(staging_dir):
|
||||
self.log.debug(f"__ test file: `{f}`")
|
||||
# filter out by not sharing the same name
|
||||
if os.path.splitext(f)[0] not in basename:
|
||||
continue
|
||||
# filter out by respected extensions
|
||||
if os.path.splitext(f)[1] not in self.extensions:
|
||||
continue
|
||||
video_path = os.path.join(
|
||||
staging_dir, f
|
||||
for representation in instance.data["representations"]:
|
||||
self.log.debug(f"__ representation: `{representation}`")
|
||||
# make editorial sequence file path
|
||||
staging_dir = representation["stagingDir"]
|
||||
file_path = os.path.join(
|
||||
staging_dir, str(representation["files"])
|
||||
)
|
||||
self.log.debug(f"__ video_path: `{video_path}`")
|
||||
instance.context.data["editorialVideoPath"] = video_path
|
||||
|
||||
# get editorial sequence file into otio timeline object
|
||||
extension = os.path.splitext(file_path)[1]
|
||||
kwargs = {}
|
||||
if extension == ".edl":
|
||||
# EDL has no frame rate embedded so needs explicit frame rate else
|
||||
# 24 is asssumed.
|
||||
kwargs["rate"] = plib.get_asset()["data"]["fps"]
|
||||
# get video file path
|
||||
video_path = None
|
||||
basename = os.path.splitext(os.path.basename(file_path))[0]
|
||||
for f in os.listdir(staging_dir):
|
||||
self.log.debug(f"__ test file: `{f}`")
|
||||
# filter out by not sharing the same name
|
||||
if os.path.splitext(f)[0] not in basename:
|
||||
continue
|
||||
# filter out by respected extensions
|
||||
if os.path.splitext(f)[1] not in self.extensions:
|
||||
continue
|
||||
video_path = os.path.join(
|
||||
staging_dir, f
|
||||
)
|
||||
self.log.debug(f"__ video_path: `{video_path}`")
|
||||
instance.data["editorialVideoPath"] = video_path
|
||||
|
||||
instance.data["otio_timeline"] = otio.adapters.read_from_file(
|
||||
file_path, **kwargs)
|
||||
# get editorial sequence file into otio timeline object
|
||||
extension = os.path.splitext(file_path)[1]
|
||||
kwargs = {}
|
||||
if extension == ".edl":
|
||||
# EDL has no frame rate embedded so needs explicit frame rate else
|
||||
# 24 is asssumed.
|
||||
kwargs["rate"] = plib.get_asset()["data"]["fps"]
|
||||
|
||||
self.log.info(f"Added OTIO timeline from: `{file_path}`")
|
||||
instance.data["otio_timeline"] = otio.adapters.read_from_file(
|
||||
file_path, **kwargs)
|
||||
|
||||
self.log.info(f"Added OTIO timeline from: `{file_path}`")
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class CollectClipFrameRanges(pyblish.api.InstancePlugin):
|
|||
|
||||
# presets
|
||||
start_frame_offset = None # if 900000 for edl default then -900000
|
||||
custom_start_frame = None
|
||||
custom_start_frame = 1
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import pyblish.api
|
|||
import avalon.api as avalon
|
||||
import re
|
||||
import os
|
||||
|
||||
from avalon import io
|
||||
|
||||
class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
||||
"""Collecting hierarchy context from `parents` and `hierarchy` data
|
||||
|
|
@ -19,14 +19,19 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
families = ["clip"]
|
||||
|
||||
# presets
|
||||
search_patterns = {
|
||||
"sequence": r"sc\d{3}",
|
||||
"shot": r"sh\d{3}",
|
||||
"episode": r"ep\d{2}"
|
||||
shot_rename_template = "{project[code]}{_episode_}{clip_name}"
|
||||
shot_rename_search_patterns = {
|
||||
"_sequence_": "sc\\d{3}",
|
||||
"_shot_": "sh\\d{3}",
|
||||
"_episode_": "ep\\d{2}"
|
||||
}
|
||||
shot_name_template = "{project[code]}{episode}{clip_name}"
|
||||
shot_hierarchy = "{episode}{sequence}/{clip_name}"
|
||||
shot_tasks = ["Animation", "Layout"]
|
||||
shot_add_hierarchy = {
|
||||
"parents_path": "{sequence}",
|
||||
"parents": {
|
||||
"sequence": "{_episode_}{_sequence_}",
|
||||
}
|
||||
}
|
||||
shot_add_tasks = ["Animation", "Layout"]
|
||||
|
||||
def convert_to_entity(self, key, value):
|
||||
# ftrack compatible entity types
|
||||
|
|
@ -43,181 +48,103 @@ class CollectHierarchyInstance(pyblish.api.InstancePlugin):
|
|||
if entity_type:
|
||||
return {"entityType": entity_type, "entityName": value}
|
||||
|
||||
def process(self, instance):
|
||||
def rename_with_hierarchy(self, instance):
|
||||
search_text = ""
|
||||
context = instance.context
|
||||
anatomy_data = context.data["anatomyData"]
|
||||
asset_entity = context.data["assetEntity"]
|
||||
asset_name = asset_entity["name"]
|
||||
assets_shared = context.data.get("assetsShared")
|
||||
|
||||
parent_name = self.asset_entity["name"]
|
||||
clip = instance.data["item"]
|
||||
clip_name = os.path.splitext(clip.name)[0].lower()
|
||||
asset = instance.data["asset"]
|
||||
|
||||
clip_in = instance.data["clipIn"]
|
||||
clip_out = instance.data["clipOut"]
|
||||
fps = instance.data["fps"]
|
||||
|
||||
hierarchy_data = dict(anatomy_data)
|
||||
if self.search_patterns:
|
||||
search_text += clip_name + asset_name
|
||||
hierarchy_data.update({"clip_name": clip_name})
|
||||
for type, pattern in self.search_patterns.items():
|
||||
if self.shot_rename_search_patterns:
|
||||
search_text += parent_name + clip_name
|
||||
self.hierarchy_data.update({"clip_name": clip_name})
|
||||
for type, pattern in self.shot_rename_search_patterns.items():
|
||||
p = re.compile(pattern)
|
||||
match = p.findall(search_text)
|
||||
if not match:
|
||||
continue
|
||||
hierarchy_data[type] = match[-1]
|
||||
self.hierarchy_data[type] = match[-1]
|
||||
|
||||
self.log.debug("__ hierarchy_data: {}".format(hierarchy_data))
|
||||
shot_name = self.shot_name_template.format(**hierarchy_data)
|
||||
self.log.debug("__ shot_name: {}".format(shot_name))
|
||||
shot_hierarchy = self.shot_hierarchy.format(**hierarchy_data)
|
||||
self.log.debug("__ shot_hierarchy: {}".format(shot_hierarchy))
|
||||
self.log.debug("__ hierarchy_data: {}".format(self.hierarchy_data))
|
||||
|
||||
# # build data for inner nukestudio project property
|
||||
# data = {
|
||||
# "sequence": (
|
||||
# context.data['activeSequence'].name().replace(' ', '_')
|
||||
# ),
|
||||
# "track": clip.parent().name().replace(' ', '_'),
|
||||
# "clip": asset
|
||||
# }
|
||||
# self.log.debug("__ data: {}".format(data))
|
||||
#
|
||||
# # Check for clips with the same range
|
||||
# # this is for testing if any vertically neighbouring
|
||||
# # clips has been already processed
|
||||
# match = next((
|
||||
# k for k, v in assets_shared.items()
|
||||
# if (v["_clipIn"] == clip_in)
|
||||
# and (v["_clipOut"] == clip_out)
|
||||
# ), False)
|
||||
#
|
||||
# self.log.debug(
|
||||
# "__ assets_shared[match]: {}".format(
|
||||
# assets_shared[match]))
|
||||
#
|
||||
# # check if hierarchy key is present in matched
|
||||
# # vertically neighbouring clip
|
||||
# if not assets_shared[match].get("hierarchy"):
|
||||
# match = False
|
||||
#
|
||||
# # rise exception if multiple hierarchy tag found
|
||||
# assert not match, (
|
||||
# "Two clips above each other with"
|
||||
# " hierarchy tag are not allowed"
|
||||
# " >> keep hierarchy tag only in one of them <<"
|
||||
# )
|
||||
#
|
||||
# d_metadata = dict()
|
||||
# parents = list()
|
||||
#
|
||||
# # main template from Tag.note
|
||||
# template = t_note
|
||||
#
|
||||
# # if shot in template then remove it
|
||||
# if "shot" in template.lower():
|
||||
# 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)
|
||||
# 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
|
||||
# # add to individual properties
|
||||
# new_v = str(v).format(
|
||||
# **dict(context.data, **data))
|
||||
# d_metadata[new_k] = new_v
|
||||
#
|
||||
# # create parents
|
||||
# # find matching index of order
|
||||
# p_match_i = [i for i, p in enumerate(par_split)
|
||||
# if new_k in p]
|
||||
#
|
||||
# # if any is matching then convert to entity_types
|
||||
# if p_match_i:
|
||||
# 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
|
||||
#
|
||||
# # create new shot asset name
|
||||
# instance.data["asset"] = instance.data["asset"].format(
|
||||
# **d_metadata)
|
||||
# self.log.debug(
|
||||
# "__ instance.data[asset]: "
|
||||
# "{}".format(instance.data["asset"])
|
||||
# )
|
||||
#
|
||||
# # 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]
|
||||
# self.log.debug("__ parents: {}".format(parents))
|
||||
#
|
||||
# hierarchy = template.format(
|
||||
# **d_metadata)
|
||||
# self.log.debug("__ hierarchy: {}".format(hierarchy))
|
||||
#
|
||||
# # check if hierarchy attribute is already created
|
||||
# # it should not be so return warning if it is
|
||||
# hd = instance.data.get("hierarchy")
|
||||
# assert not hd, (
|
||||
# "Only one Hierarchy Tag is allowed. "
|
||||
# "Clip: `{}`".format(asset)
|
||||
# )
|
||||
#
|
||||
# # add formated hierarchy path into instance data
|
||||
# instance.data["hierarchy"] = hierarchy
|
||||
# instance.data["parents"] = parents
|
||||
#
|
||||
# self.log.info(
|
||||
# "clip: {asset}[{clip_in}:{clip_out}]".format(
|
||||
# **locals()))
|
||||
# # adding to asset shared dict
|
||||
# self.log.debug(
|
||||
# "__ assets_shared: {}".format(assets_shared))
|
||||
# if assets_shared.get(asset):
|
||||
# self.log.debug("Adding to shared assets: `{}`".format(
|
||||
# asset))
|
||||
# asset_shared = assets_shared.get(asset)
|
||||
# else:
|
||||
# asset_shared = assets_shared[asset]
|
||||
#
|
||||
# asset_shared.update({
|
||||
# "asset": asset,
|
||||
# "hierarchy": hierarchy,
|
||||
# "parents": parents,
|
||||
# "fps": fps,
|
||||
# "tasks": instance.data["tasks"]
|
||||
# })
|
||||
#
|
||||
# # adding frame start if any on instance
|
||||
# start_frame = instance.data.get("startingFrame")
|
||||
# if start_frame:
|
||||
# asset_shared.update({
|
||||
# "startingFrame": start_frame
|
||||
# })
|
||||
# self.log.debug(
|
||||
# "assets_shared: {assets_shared}".format(**locals()))
|
||||
# format to new shot name
|
||||
self.shot_name = self.shot_rename_template.format(
|
||||
**self.hierarchy_data)
|
||||
instance.data["asset"] = self.shot_name
|
||||
self.log.debug("__ self.shot_name: {}".format(self.shot_name))
|
||||
|
||||
def create_hierarchy(self, instance):
|
||||
parents = list()
|
||||
hierarchy = ""
|
||||
visual_hierarchy = [self.asset_entity]
|
||||
while True:
|
||||
visual_parent = io.find_one(
|
||||
{"_id": visual_hierarchy[-1]["data"]["visualParent"]}
|
||||
)
|
||||
if visual_parent:
|
||||
visual_hierarchy.append(visual_parent)
|
||||
else:
|
||||
visual_hierarchy.append(
|
||||
instance.context.data["projectEntity"])
|
||||
break
|
||||
self.log.debug("__ visual_hierarchy: {}".format(visual_hierarchy))
|
||||
|
||||
# add current selection context hierarchy from standalonepublisher
|
||||
for entity in reversed(visual_hierarchy):
|
||||
parents.append({
|
||||
"entityType": entity["data"]["entityType"],
|
||||
"entityName": entity["name"]
|
||||
})
|
||||
|
||||
if self.shot_add_hierarchy:
|
||||
# fill the parents parts from presets
|
||||
for parent in self.shot_add_hierarchy["parents"]:
|
||||
if not self.shot_add_hierarchy["parents"][parent]:
|
||||
prnt = {"entity"}
|
||||
else:
|
||||
self.shot_add_hierarchy["parents"][parent] = self.shot_add_hierarchy[
|
||||
"parents"][parent].format(**self.hierarchy_data)
|
||||
prnt = self.convert_to_entity(
|
||||
parent, self.shot_add_hierarchy["parents"][parent])
|
||||
parents.append(prnt)
|
||||
|
||||
hierarchy = self.shot_add_hierarchy[
|
||||
"parents_path"].format(**self.shot_add_hierarchy["parents"])
|
||||
|
||||
instance.data["hierarchy"] = hierarchy
|
||||
instance.data["parents"] = parents
|
||||
|
||||
if self.shot_add_tasks:
|
||||
instance.data["tasks"] = self.shot_add_tasks
|
||||
else:
|
||||
instance.data["tasks"] = list()
|
||||
|
||||
def process(self, instance):
|
||||
assets_shared = instance.context.data.get("assetsShared")
|
||||
context = instance.context
|
||||
anatomy_data = context.data["anatomyData"]
|
||||
|
||||
self.shot_name = instance.data["asset"]
|
||||
self.hierarchy_data = dict(anatomy_data)
|
||||
self.asset_entity = context.data["assetEntity"]
|
||||
|
||||
frame_start = instance.data["frameStart"]
|
||||
frame_end = instance.data["frameEnd"]
|
||||
|
||||
if self.shot_rename_template:
|
||||
self.rename_with_hierarchy(instance)
|
||||
|
||||
self.create_hierarchy(instance)
|
||||
|
||||
label = f"{self.shot_name} ({frame_start}-{frame_end})"
|
||||
instance.data["label"] = label
|
||||
|
||||
assets_shared[self.shot_name] = {
|
||||
"asset": instance.data["asset"],
|
||||
"hierarchy": instance.data["hierarchy"],
|
||||
"parents": instance.data["parents"],
|
||||
"fps": instance.data["fps"],
|
||||
"tasks": instance.data["tasks"]
|
||||
}
|
||||
|
||||
|
||||
class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
||||
|
|
@ -242,13 +169,12 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
return new_dict
|
||||
|
||||
def process(self, context):
|
||||
instances = context[:]
|
||||
|
||||
instances = context
|
||||
# create hierarchyContext attr if context has none
|
||||
|
||||
temp_context = {}
|
||||
final_context = {}
|
||||
for instance in instances:
|
||||
if 'projectfile' in instance.data.get('family', ''):
|
||||
if 'clip' not in instance.data.get('family', ''):
|
||||
continue
|
||||
|
||||
name = instance.data["asset"]
|
||||
|
|
@ -268,11 +194,6 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
instance.data["parents"] = s_asset_data["parents"]
|
||||
instance.data["hierarchy"] = s_asset_data["hierarchy"]
|
||||
instance.data["tasks"] = s_asset_data["tasks"]
|
||||
instance.data["resolutionWidth"] = s_asset_data[
|
||||
"resolutionWidth"]
|
||||
instance.data["resolutionHeight"] = s_asset_data[
|
||||
"resolutionHeight"]
|
||||
instance.data["pixelAspect"] = s_asset_data["pixelAspect"]
|
||||
instance.data["fps"] = s_asset_data["fps"]
|
||||
|
||||
# adding frame start if any on instance
|
||||
|
|
@ -283,8 +204,6 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
instance.data["clipOut"] -
|
||||
instance.data["clipIn"])
|
||||
|
||||
|
||||
|
||||
self.log.debug(
|
||||
"__ instance.data[parents]: {}".format(
|
||||
instance.data["parents"]
|
||||
|
|
@ -301,32 +220,20 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
|
||||
in_info = {}
|
||||
|
||||
in_info["inputs"] = [
|
||||
x["_id"] for x in instance.data.get("assetbuilds", [])
|
||||
]
|
||||
|
||||
# suppose that all instances are Shots
|
||||
in_info['entity_type'] = 'Shot'
|
||||
|
||||
# get custom attributes of the shot
|
||||
if instance.data.get("main"):
|
||||
in_info['custom_attributes'] = {
|
||||
"handleStart": handle_start,
|
||||
"handleEnd": handle_end,
|
||||
"frameStart": instance.data["frameStart"],
|
||||
"frameEnd": instance.data["frameEnd"],
|
||||
"clipIn": instance.data["clipIn"],
|
||||
"clipOut": instance.data["clipOut"],
|
||||
'fps': instance.context.data["fps"]
|
||||
}
|
||||
|
||||
# adding SourceResolution if Tag was present
|
||||
if instance.data.get("main"):
|
||||
in_info['custom_attributes'].update({
|
||||
"resolutionWidth": instance.data["resolutionWidth"],
|
||||
"resolutionHeight": instance.data["resolutionHeight"],
|
||||
"pixelAspect": instance.data["pixelAspect"]
|
||||
})
|
||||
in_info['custom_attributes'] = {
|
||||
"handleStart": handle_start,
|
||||
"handleEnd": handle_end,
|
||||
"frameStart": instance.data["frameStart"],
|
||||
"frameEnd": instance.data["frameEnd"],
|
||||
"clipIn": instance.data["clipIn"],
|
||||
"clipOut": instance.data["clipOut"],
|
||||
'fps': instance.data["fps"]
|
||||
}
|
||||
|
||||
in_info['tasks'] = instance.data['tasks']
|
||||
|
||||
|
|
@ -343,14 +250,7 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):
|
|||
next_dict[parent_name]["childs"] = actual
|
||||
actual = next_dict
|
||||
|
||||
temp_context = self.update_dict(temp_context, actual)
|
||||
|
||||
# TODO: 100% sure way of get project! Will be Name or Code?
|
||||
project_name = avalon.Session["AVALON_PROJECT"]
|
||||
final_context = {}
|
||||
final_context[project_name] = {}
|
||||
final_context[project_name]['entity_type'] = 'Project'
|
||||
final_context[project_name]['childs'] = temp_context
|
||||
final_context = self.update_dict(final_context, actual)
|
||||
|
||||
# adding hierarchy context to instance
|
||||
context.data["hierarchyContext"] = final_context
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
import pyblish.api
|
||||
import re
|
||||
|
||||
|
||||
class CollectShotNames(pyblish.api.InstancePlugin):
|
||||
"""
|
||||
Collecting shot names
|
||||
"""
|
||||
|
||||
label = "Collect shot names"
|
||||
order = pyblish.api.CollectorOrder + 0.01
|
||||
hosts = ["standalonepublisher"]
|
||||
|
||||
def process(self, instance):
|
||||
self.log.info("Instance name: `{}`".format(instance.data["name"]))
|
||||
|
|
@ -12,9 +12,6 @@ class ExtractShot(pype.api.Extractor):
|
|||
families = ["clip"]
|
||||
|
||||
def process(self, instance):
|
||||
# get context
|
||||
context = instance.context
|
||||
|
||||
# get ffmpet path
|
||||
ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg")
|
||||
|
||||
|
|
@ -24,7 +21,7 @@ class ExtractShot(pype.api.Extractor):
|
|||
|
||||
# Generate mov file.
|
||||
fps = instance.data["fps"]
|
||||
video_file_path = context.data["editorialVideoPath"]
|
||||
video_file_path = instance.data["editorialVideoPath"]
|
||||
ext = os.path.splitext(os.path.basename(video_file_path))[-1]
|
||||
|
||||
clip_trimed_path = os.path.join(
|
||||
|
|
@ -60,7 +57,7 @@ class ExtractShot(pype.api.Extractor):
|
|||
"frameEnd": instance.data["frameEnd"],
|
||||
"fps": fps,
|
||||
"thumbnail": True,
|
||||
"tags": ["review", "ftrackreview"]
|
||||
"tags": ["review", "ftrackreview", "delete"]
|
||||
})
|
||||
|
||||
# # Generate jpegs.
|
||||
|
|
|
|||
|
|
@ -9,24 +9,10 @@ class ValidateEditorialResources(pyblish.api.InstancePlugin):
|
|||
|
||||
label = "Validate Editorial Resources"
|
||||
hosts = ["standalonepublisher"]
|
||||
families = ["editorial"]
|
||||
families = ["clip"]
|
||||
order = pype.api.ValidateContentsOrder
|
||||
|
||||
# presets
|
||||
check_ext = None
|
||||
|
||||
def process(self, instance):
|
||||
check_ext = self.check_ext or "mov"
|
||||
representation = instance.data["representations"][0]
|
||||
staging_dir = representation["stagingDir"]
|
||||
basename = os.path.splitext(
|
||||
os.path.basename(representation["files"])
|
||||
)[0]
|
||||
|
||||
files = [x for x in os.listdir(staging_dir)]
|
||||
|
||||
# Check for correct extansion in file name.
|
||||
filename = basename + check_ext
|
||||
filepath = os.path.join(staging_dir, filename)
|
||||
msg = f"Missing \"{filepath}\"."
|
||||
assert filename in files, msg
|
||||
check_file = instance.data["editorialVideoPath"]
|
||||
msg = f"Missing \"{check_file}\"."
|
||||
assert check_file, msg
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue