Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1172 from tokejepsen/2.x/feature/hiero_frame_publish
Browse files Browse the repository at this point in the history
  • Loading branch information
mkolar authored May 27, 2021
2 parents 7f27aca + e338c05 commit bc25e27
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 2 deletions.
12 changes: 12 additions & 0 deletions pype/hosts/hiero/tags.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@
"subset": "proxy"
}
},
"frameMain": {
"editable": "1",
"note": "Add to publish frame \"main\" subset.",
"icon": {
"path": "z_layer_main.png"
},
"metadata": {
"family": "frame",
"subset": "main",
"format": "png"
}
},
"review": {
"editable": "1",
"note": "Upload to Ftrack as review component.",
Expand Down
4 changes: 2 additions & 2 deletions pype/plugins/hiero/publish/collect_frame_ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CollectClipFrameRanges(pyblish.api.InstancePlugin):
order = pyblish.api.CollectorOrder + 0.101
label = "Collect Frame Ranges"
hosts = ["hiero"]
families = ["clip"]

def process(self, instance):
data = {}
Expand Down Expand Up @@ -55,7 +56,6 @@ def process(self, instance):
"clipOutH": timeline_out_h,
"clipDurationH": instance.data.get(
"clipDuration") + handle_start + handle_end
}
)
})
self.log.debug("__ data: {}".format(data))
instance.data.update(data)
77 changes: 77 additions & 0 deletions pype/plugins/hiero/publish/collect_frames.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import json

import hiero

from pyblish import api


class CollectFrames(api.ContextPlugin):
"""Collect frames from tags.
Tag is expected to have metadata:
{
"family": "frame"
"subset": "main"
}
"""

order = api.CollectorOrder
label = "Collect Frames"
hosts = ["hiero"]

def process(self, context):
sequence = hiero.ui.activeSequence()

publish_frames = range(
int(sequence.timecodeStart()),
int(sequence.duration() + sequence.timecodeStart())
)
selection = hiero.selection
if selection:
publish_frames = []
for track_item in selection:
publish_frames.extend(
range(track_item.timelineIn(), track_item.timelineOut())
)

publish_frames = list(set(publish_frames))

subset_data = {}
for tag in sequence.tags():
metadata = tag.metadata().dict()
if "tag.family" not in metadata:
continue
if metadata["tag.family"] != "frame":
continue

frame = int(metadata["tag.start"])

if frame not in publish_frames:
continue

subset = metadata["tag.subset"]
try:
subset_data[subset]["frames"].append(frame)
except KeyError:
subset_data[subset] = {
"frames": [frame], "format": metadata["tag.format"]
}

for subset_name, subset_data in subset_data.items():
name = "frame" + subset_name.title()
data = {
"name": name,
"label": "{} {}".format(name, subset_data["frames"]),
"family": "image",
"families": ["frame"],
"asset": context.data["assetEntity"]["name"],
"subset": subset_name,
"format": subset_data["format"],
"frames": subset_data["frames"]
}
context.create_instance(**data)
self.log.info(
"Created instance: {}".format(
json.dumps(data, sort_keys=True, indent=4)
)
)
9 changes: 9 additions & 0 deletions pype/plugins/hiero/publish/collect_hierarchy_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ def convert_to_entity(self, key, value):
def process(self, context):

for instance in context[:]:
if instance.data["family"] not in self.families:
continue

assets_shared = context.data.get("assetsShared")
tags = instance.data.get("tags", None)
clip = instance.data["item"]
Expand Down Expand Up @@ -218,6 +221,7 @@ class CollectHierarchyContext(pyblish.api.ContextPlugin):

label = "Collect Hierarchy Context"
order = pyblish.api.CollectorOrder + 0.103
exclude_families = ["frame"]

def update_dict(self, ex_dict, new_dict):
for key in ex_dict:
Expand All @@ -238,6 +242,11 @@ def process(self, context):

temp_context = {}
for instance in instances:
families = instance.data.get("families", [])
families += [instance.data["family"]]
if set(families) & set(self.exclude_families):
continue

if 'projectfile' in instance.data.get('family', ''):
continue

Expand Down
3 changes: 3 additions & 0 deletions pype/plugins/hiero/publish/collect_tag_handles.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class CollectClipTagHandles(api.ContextPlugin):
def process(self, context):
assets_shared = context.data.get("assetsShared")
for instance in context[:]:
if instance.data["family"] not in self.families:
continue

self.log.info("Instance.name: `{}`".format(
instance.data["name"]))
# gets tags
Expand Down
84 changes: 84 additions & 0 deletions pype/plugins/hiero/publish/extract_frames.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import os

import hiero

from pyblish import api

import pype


class ExtractFrames(pype.api.Extractor):
"""Extracts frames"""

order = api.ExtractorOrder
label = "Extract Frames"
hosts = ["hiero"]
families = ["frame"]
movie_extensions = ["mov"]

def process(self, instance):
staging_dir = self.staging_dir(instance)
output_template = os.path.join(staging_dir, instance.data["name"])
sequence = hiero.ui.activeSequence()
files = []
for frame in instance.data["frames"]:
track_item = sequence.trackItemAt(frame)
media_source = track_item.source().mediaSource()
input_path = media_source.fileinfos()[0].filename()
input_frame = (
track_item.mapTimelineToSource(frame) +
track_item.source().mediaSource().startTime()
)
format = instance.data["format"]
output_path = output_template
output_path += ".{:04d}.{}".format(int(frame), format)

args = ["oiiotool"]

ext = os.path.splitext(input_path)[1][1:]
if ext in self.movie_extensions:
args.extend(["--subimage", str(int(input_frame))])
else:
args.extend(["--frames", str(int(input_frame))])

if ext == "exr":
args.extend(["--powc", "0.45,0.45,0.45,1.0"])

args.extend([input_path, "-o", output_path])
output = pype.api.subprocess(args)

failed_output = "oiiotool produced no output."
if failed_output in output:
raise ValueError(
"oiiotool processing failed. Args: {}".format(args)
)

files.append(output_path)

# Feedback to user because "oiiotool" can make the publishing
# appear unresponsive.
self.log.info(
"Processed {} of {} frames".format(
instance.data["frames"].index(frame) + 1,
len(instance.data["frames"])
)
)

if len(files) == 1:
instance.data["representations"] = [
{
"name": format,
"ext": format,
"files": os.path.basename(files[0]),
"stagingDir": staging_dir
}
]
else:
instance.data["representations"] = [
{
"name": format,
"ext": format,
"files": [os.path.basename(x) for x in files],
"stagingDir": staging_dir
}
]

0 comments on commit bc25e27

Please sign in to comment.