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

Commit

Permalink
Merge branch 'feature/1376-hiero-publish-color-and-transformation-sof…
Browse files Browse the repository at this point in the history
…t-effects' into feature/1377-hiero-publish-with-retiming
  • Loading branch information
jakubjezek001 committed May 20, 2021
2 parents fb45010 + 3dd4cc0 commit 45c7fe6
Show file tree
Hide file tree
Showing 10 changed files with 212 additions and 46 deletions.
4 changes: 3 additions & 1 deletion openpype/hosts/hiero/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,9 @@ def get_track_items(
# add all if no track_type is defined
return_list.append(track_item)

return return_list
# return output list but make sure all items are TrackItems
return [_i for _i in return_list
if type(_i) == hiero.core.TrackItem]


def get_track_item_pype_tag(track_item):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ def process(self, instance):
instance.data["representations"] = list()

transfer_data = [
"handleStart", "handleEnd", "sourceIn", "sourceOut",
"frameStart", "frameEnd", "sourceInH", "sourceOutH",
"clipIn", "clipOut", "clipInH", "clipOutH", "asset", "track",
"version"
"handleStart", "handleEnd",
"sourceStart", "sourceStartH", "sourceEnd", "sourceEndH",
"frameStart", "frameEnd",
"clipIn", "clipOut", "clipInH", "clipOutH",
"asset", "version"
]

# pass data to version
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class PreCollectClipEffects(pyblish.api.InstancePlugin):
"""Collect soft effects instances."""

order = pyblish.api.CollectorOrder - 0.508
order = pyblish.api.CollectorOrder - 0.579
label = "Pre-collect Clip Effects Instances"
families = ["clip"]

Expand All @@ -24,7 +24,8 @@ def process(self, instance):
self.clip_in_h = self.clip_in - self.handle_start
self.clip_out_h = self.clip_out + self.handle_end

track = instance.data["trackItem"]
track_item = instance.data["item"]
track = track_item.parent()
track_index = track.trackIndex()
tracks_effect_items = instance.context.data.get("tracksEffectItems")
clip_effect_items = instance.data.get("clipEffectItems")
Expand Down Expand Up @@ -112,7 +113,12 @@ def add_effect(self, track_index, sitem):
node = sitem.node()
node_serialized = self.node_serialisation(node)
node_name = sitem.name()
node_class = re.sub(r"\d+", "", node_name)

if "_" in node_name:
node_class = re.sub(r"(?:_)[_0-9]+", "", node_name) # more numbers
else:
node_class = re.sub(r"\d+", "", node_name) # one number

# collect timelineIn/Out
effect_t_in = int(sitem.timelineIn())
effect_t_out = int(sitem.timelineOut())
Expand All @@ -121,6 +127,7 @@ def add_effect(self, track_index, sitem):
return

self.log.debug("node_name: `{}`".format(node_name))
self.log.debug("node_class: `{}`".format(node_class))

return {node_name: {
"class": node_class,
Expand Down
140 changes: 133 additions & 7 deletions openpype/hosts/hiero/plugins/publish/precollect_instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import openpype
from openpype.hosts.hiero import api as phiero
from openpype.hosts.hiero.otio import hiero_export
import hiero

from compiler.ast import flatten

# # developer reload modules
from pprint import pformat
Expand All @@ -14,18 +17,40 @@ class PrecollectInstances(pyblish.api.ContextPlugin):
label = "Precollect Instances"
hosts = ["hiero"]

audio_track_items = []

def process(self, context):
otio_timeline = context.data["otioTimeline"]
self.otio_timeline = context.data["otioTimeline"]

selected_timeline_items = phiero.get_track_items(
selected=True, check_enabled=True, check_tagged=True)
selected=True, check_tagged=True, check_enabled=True)

# only return enabled track items
if not selected_timeline_items:
selected_timeline_items = phiero.get_track_items(
check_enabled=True, check_tagged=True)

self.log.info(
"Processing enabled track items: {}".format(
selected_timeline_items))

# add all tracks subtreck effect items to context
all_tracks = hiero.ui.activeSequence().videoTracks()
tracks_effect_items = self.collect_sub_track_items(all_tracks)
context.data["tracksEffectItems"] = tracks_effect_items

# process all sellected timeline track items
for track_item in selected_timeline_items:

data = {}
clip_name = track_item.name()
source_clip = track_item.source()

# get clips subtracks and anotations
annotations = self.clip_annotations(source_clip)
subtracks = self.clip_subtrack(track_item)
self.log.debug("Annotations: {}".format(annotations))
self.log.debug(">> Subtracks: {}".format(subtracks))

# get openpype tag data
tag_data = phiero.get_track_item_pype_data(track_item)
Expand Down Expand Up @@ -76,12 +101,15 @@ def process(self, context):
"item": track_item,
"families": families,
"publish": tag_data["publish"],
"fps": context.data["fps"]
"fps": context.data["fps"],

# clip's effect
"clipEffectItems": subtracks,
"clipAnnotations": annotations
})

# otio clip data
otio_data = self.get_otio_clip_instance_data(
otio_timeline, track_item) or {}
otio_data = self.get_otio_clip_instance_data(track_item) or {}
self.log.debug("__ otio_data: {}".format(pformat(otio_data)))
data.update(otio_data)
self.log.debug("__ data: {}".format(pformat(data)))
Expand Down Expand Up @@ -185,6 +213,10 @@ def create_audio_instance(self, context, **data):
item = data.get("item")
clip_name = item.name()

# test if any audio clips
if not self.test_any_audio(item):
return

asset = data["asset"]
subset = "audioMain"

Expand Down Expand Up @@ -215,7 +247,28 @@ def create_audio_instance(self, context, **data):
self.log.debug(
"_ instance.data: {}".format(pformat(instance.data)))

def get_otio_clip_instance_data(self, otio_timeline, track_item):
def test_any_audio(self, track_item):
# collect all audio tracks to class variable
if not self.audio_track_items:
for otio_clip in self.otio_timeline.each_clip():
if otio_clip.parent().kind != "Audio":
continue
self.audio_track_items.append(otio_clip)

# get track item timeline range
timeline_range = self.create_otio_time_range_from_timeline_item_data(
track_item)

# loop trough audio track items and search for overlaping clip
for otio_audio in self.audio_track_items:
parent_range = otio_audio.range_in_parent()

# if any overaling clip found then return True
if openpype.lib.is_overlapping_otio_ranges(
parent_range, timeline_range, strict=False):
return True

def get_otio_clip_instance_data(self, track_item):
"""
Return otio objects for timeline, track and clip
Expand All @@ -231,7 +284,7 @@ def get_otio_clip_instance_data(self, otio_timeline, track_item):
ti_track_name = track_item.parent().name()
timeline_range = self.create_otio_time_range_from_timeline_item_data(
track_item)
for otio_clip in otio_timeline.each_clip():
for otio_clip in self.otio_timeline.each_clip():
track_name = otio_clip.parent().name
parent_range = otio_clip.range_in_parent()
if ti_track_name not in track_name:
Expand All @@ -258,3 +311,76 @@ def create_otio_time_range_from_timeline_item_data(track_item):

return hiero_export.create_otio_time_range(
frame_start, frame_duration, fps)

@staticmethod
def collect_sub_track_items(tracks):
"""
Returns dictionary with track index as key and list of subtracks
"""
# collect all subtrack items
sub_track_items = {}
for track in tracks:
items = track.items()

# skip if no clips on track > need track with effect only
if items:
continue

# skip all disabled tracks
if not track.isEnabled():
continue

track_index = track.trackIndex()
_sub_track_items = flatten(track.subTrackItems())

# continue only if any subtrack items are collected
if len(_sub_track_items) < 1:
continue

enabled_sti = []
# loop all found subtrack items and check if they are enabled
for _sti in _sub_track_items:
# checking if not enabled
if not _sti.isEnabled():
continue
if isinstance(_sti, hiero.core.Annotation):
continue
# collect the subtrack item
enabled_sti.append(_sti)

# continue only if any subtrack items are collected
if len(enabled_sti) < 1:
continue

# add collection of subtrackitems to dict
sub_track_items[track_index] = enabled_sti

return sub_track_items

@staticmethod
def clip_annotations(clip):
"""
Returns list of Clip's hiero.core.Annotation
"""
annotations = []
subTrackItems = flatten(clip.subTrackItems())
annotations += [item for item in subTrackItems if isinstance(
item, hiero.core.Annotation)]
return annotations

@staticmethod
def clip_subtrack(clip):
"""
Returns list of Clip's hiero.core.SubTrackItem
"""
subtracks = []
subTrackItems = flatten(clip.parent().subTrackItems())
for item in subTrackItems:
# avoid all anotation
if isinstance(item, hiero.core.Annotation):
continue
# # avoid all not anaibled
if not item.isEnabled():
continue
subtracks.append(item)
return subtracks
18 changes: 17 additions & 1 deletion openpype/hosts/hiero/plugins/publish/precollect_workfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,26 @@ def process(self, context):
"activeProject": project,
"otioTimeline": otio_timeline,
"currentFile": curent_file,
"fps": fps,
"colorspace": self.get_colorspace(project),
"fps": fps
}
context.data.update(context_data)

self.log.info("Creating instance: {}".format(instance))
self.log.debug("__ instance.data: {}".format(pformat(instance.data)))
self.log.debug("__ context_data: {}".format(pformat(context_data)))

def get_colorspace(self, project):
# get workfile's colorspace properties
return {
"useOCIOEnvironmentOverride": project.useOCIOEnvironmentOverride(),
"lutSetting16Bit": project.lutSetting16Bit(),
"lutSetting8Bit": project.lutSetting8Bit(),
"lutSettingFloat": project.lutSettingFloat(),
"lutSettingLog": project.lutSettingLog(),
"lutSettingViewer": project.lutSettingViewer(),
"lutSettingWorkingSpace": project.lutSettingWorkingSpace(),
"lutUseOCIOForExport": project.lutUseOCIOForExport(),
"ocioConfigName": project.ocioConfigName(),
"ocioConfigPath": project.ocioConfigPath()
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
from collections import OrderedDict


class LoadLuts(api.Loader):
class LoadEffects(api.Loader):
"""Loading colorspace soft effect exported from nukestudio"""

representations = ["lutJson"]
families = ["lut"]
representations = ["effectJson"]
families = ["effect"]

label = "Load Luts - nodes"
label = "Load Effects - nodes"
order = 0
icon = "cc"
color = style.colors.light
ignore_attr = ["useLifetime"]


def load(self, context, name, namespace, data):
"""
Loading function to get the soft effects to particular read node
Expand Down Expand Up @@ -66,15 +67,15 @@ def load(self, context, name, namespace, data):
for key, value in json.load(f).iteritems()}

# get correct order of nodes by positions on track and subtrack
nodes_order = self.reorder_nodes(json_f["effects"])
nodes_order = self.reorder_nodes(json_f)

# adding nodes to node graph
# just in case we are in group lets jump out of it
nuke.endGroup()

GN = nuke.createNode("Group")

GN["name"].setValue(object_name)
GN = nuke.createNode(
"Group",
"name {}_1".format(object_name))

# adding content to the group node
with GN:
Expand Down Expand Up @@ -186,7 +187,7 @@ def update(self, container, representation):
for key, value in json.load(f).iteritems()}

# get correct order of nodes by positions on track and subtrack
nodes_order = self.reorder_nodes(json_f["effects"])
nodes_order = self.reorder_nodes(json_f)

# adding nodes to node graph
# just in case we are in group lets jump out of it
Expand Down Expand Up @@ -266,7 +267,11 @@ def connect_read_node(self, group_node, asset, subset):
None: if nothing found
"""
search_name = "{0}_{1}".format(asset, subset)
node = [n for n in nuke.allNodes() if search_name in n["name"].value()]

node = [
n for n in nuke.allNodes(filter="Read")
if search_name in n["file"].value()
]
if len(node) > 0:
rn = node[0]
else:
Expand All @@ -286,8 +291,10 @@ def connect_read_node(self, group_node, asset, subset):

def reorder_nodes(self, data):
new_order = OrderedDict()
trackNums = [v["trackIndex"] for k, v in data.items()]
subTrackNums = [v["subTrackIndex"] for k, v in data.items()]
trackNums = [v["trackIndex"] for k, v in data.items()
if isinstance(v, dict)]
subTrackNums = [v["subTrackIndex"] for k, v in data.items()
if isinstance(v, dict)]

for trackIndex in range(
min(trackNums), max(trackNums) + 1):
Expand All @@ -300,6 +307,7 @@ def reorder_nodes(self, data):

def get_item(self, data, trackIndex, subTrackIndex):
return {key: val for key, val in data.items()
if isinstance(val, dict)
if subTrackIndex == val["subTrackIndex"]
if trackIndex == val["trackIndex"]}

Expand Down
Loading

0 comments on commit 45c7fe6

Please sign in to comment.