Resolve: merge openpype fixes

This commit is contained in:
Jakub Jezek 2021-04-06 15:11:00 +02:00
parent f74bf468e0
commit 9228508dff
No known key found for this signature in database
GPG key ID: C4B96E101D2A47F3
7 changed files with 100 additions and 223 deletions

View file

@ -12,7 +12,8 @@ from avalon.tools import (
creator,
loader,
sceneinventory,
libraryloader
libraryloader,
subsetmanager
)
@ -59,19 +60,20 @@ class OpenPypeMenu(QtWidgets.QWidget):
)
self.setWindowTitle("OpenPype")
workfiles_btn = QtWidgets.QPushButton("Workfiles ...", self)
create_btn = QtWidgets.QPushButton("Create ...", self)
publish_btn = QtWidgets.QPushButton("Publish ...", self)
load_btn = QtWidgets.QPushButton("Load ...", self)
inventory_btn = QtWidgets.QPushButton("Inventory ...", self)
libload_btn = QtWidgets.QPushButton("Library ...", self)
# rename_btn = QtWidgets.QPushButton("Rename ...", self)
# set_colorspace_btn = QtWidgets.QPushButton(
# "Set colorspace from presets", self
# )
# reset_resolution_btn = QtWidgets.QPushButton(
# "Reset Resolution from peresets", self
# )
workfiles_btn = QtWidgets.QPushButton("Workfiles", self)
create_btn = QtWidgets.QPushButton("Create", self)
publish_btn = QtWidgets.QPushButton("Publish", self)
load_btn = QtWidgets.QPushButton("Load", self)
inventory_btn = QtWidgets.QPushButton("Inventory", self)
subsetm_btn = QtWidgets.QPushButton("Subset Manager", self)
libload_btn = QtWidgets.QPushButton("Library", self)
rename_btn = QtWidgets.QPushButton("Rename", self)
set_colorspace_btn = QtWidgets.QPushButton(
"Set colorspace from presets", self
)
reset_resolution_btn = QtWidgets.QPushButton(
"Reset Resolution from peresets", self
)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(10, 20, 10, 20)
@ -81,19 +83,20 @@ class OpenPypeMenu(QtWidgets.QWidget):
layout.addWidget(publish_btn)
layout.addWidget(load_btn)
layout.addWidget(inventory_btn)
layout.addWidget(subsetm_btn)
layout.addWidget(Spacer(15, self))
layout.addWidget(libload_btn)
# layout.addWidget(Spacer(15, self))
layout.addWidget(Spacer(15, self))
# layout.addWidget(rename_btn)
layout.addWidget(rename_btn)
# layout.addWidget(Spacer(15, self))
layout.addWidget(Spacer(15, self))
# layout.addWidget(set_colorspace_btn)
# layout.addWidget(reset_resolution_btn)
layout.addWidget(set_colorspace_btn)
layout.addWidget(reset_resolution_btn)
self.setLayout(layout)
@ -102,10 +105,11 @@ class OpenPypeMenu(QtWidgets.QWidget):
publish_btn.clicked.connect(self.on_publish_clicked)
load_btn.clicked.connect(self.on_load_clicked)
inventory_btn.clicked.connect(self.on_inventory_clicked)
subsetm_btn.clicked.connect(self.on_subsetm_clicked)
libload_btn.clicked.connect(self.on_libload_clicked)
# rename_btn.clicked.connect(self.on_rename_clicked)
# set_colorspace_btn.clicked.connect(self.on_set_colorspace_clicked)
# reset_resolution_btn.clicked.connect(self.on_reset_resolution_clicked)
rename_btn.clicked.connect(self.on_rename_clicked)
set_colorspace_btn.clicked.connect(self.on_set_colorspace_clicked)
reset_resolution_btn.clicked.connect(self.on_reset_resolution_clicked)
def on_workfile_clicked(self):
print("Clicked Workfile")
@ -127,6 +131,10 @@ class OpenPypeMenu(QtWidgets.QWidget):
print("Clicked Inventory")
sceneinventory.show()
def on_subsetm_clicked(self):
print("Clicked Subset Manager")
subsetmanager.show()
def on_libload_clicked(self):
print("Clicked Library")
libraryloader.show()

View file

@ -258,3 +258,51 @@ def on_pyblish_instance_toggled(instance, old_value, new_value):
# Whether instances should be passthrough based on new value
timeline_item = instance.data["item"]
set_publish_attribute(timeline_item, new_value)
def remove_instance(instance):
"""Remove instance marker from track item."""
instance_id = instance.get("uuid")
selected_timeline_items = lib.get_current_timeline_items(
filter=True, selecting_color=lib.publish_clip_color)
found_ti = None
for timeline_item_data in selected_timeline_items:
timeline_item = timeline_item_data["clip"]["item"]
# get openpype tag data
tag_data = lib.get_timeline_item_pype_tag(timeline_item)
_ti_id = tag_data.get("uuid")
if _ti_id == instance_id:
found_ti = timeline_item
break
if found_ti is None:
return
# removing instance by marker color
print(f"Removing instance: {found_ti.GetName()}")
found_ti.DeleteMarkersByColor(lib.pype_marker_color)
def list_instances():
"""List all created instances from current workfile."""
listed_instances = []
selected_timeline_items = lib.get_current_timeline_items(
filter=True, selecting_color=lib.publish_clip_color)
for timeline_item_data in selected_timeline_items:
timeline_item = timeline_item_data["clip"]["item"]
ti_name = timeline_item.GetName().split(".")[0]
# get openpype tag data
tag_data = lib.get_timeline_item_pype_tag(timeline_item)
if tag_data:
asset = tag_data.get("asset")
subset = tag_data.get("subset")
tag_data["label"] = f"{ti_name} [{asset}-{subset}]"
listed_instances.append(tag_data)
return listed_instances

View file

@ -1,4 +1,5 @@
import re
import uuid
from avalon import api
import openpype.api as pype
from openpype.hosts import resolve
@ -697,13 +698,13 @@ class PublishClip:
Populating the tag data into internal variable self.tag_data
"""
# define vertical sync attributes
master_layer = True
hero_track = True
self.review_layer = ""
if self.vertical_sync:
# check if track name is not in driving layer
if self.track_name not in self.driving_layer:
# if it is not then define vertical sync as None
master_layer = False
hero_track = False
# increasing steps by index of rename iteration
self.count_steps *= self.rename_index
@ -717,7 +718,7 @@ class PublishClip:
self.tag_data[_k] = _v["value"]
# driving layer is set as positive match
if master_layer or self.vertical_sync:
if hero_track or self.vertical_sync:
# mark review layer
if self.review_track and (
self.review_track not in self.review_track_default):
@ -751,35 +752,39 @@ class PublishClip:
hierarchy_formating_data
)
tag_hierarchy_data.update({"masterLayer": True})
if master_layer and self.vertical_sync:
# tag_hierarchy_data.update({"masterLayer": True})
tag_hierarchy_data.update({"heroTrack": True})
if hero_track and self.vertical_sync:
self.vertical_clip_match.update({
(self.clip_in, self.clip_out): tag_hierarchy_data
})
if not master_layer and self.vertical_sync:
if not hero_track and self.vertical_sync:
# driving layer is set as negative match
for (_in, _out), master_data in self.vertical_clip_match.items():
master_data.update({"masterLayer": False})
for (_in, _out), hero_data in self.vertical_clip_match.items():
hero_data.update({"heroTrack": False})
if _in == self.clip_in and _out == self.clip_out:
data_subset = master_data["subset"]
# add track index in case duplicity of names in master data
data_subset = hero_data["subset"]
# add track index in case duplicity of names in hero data
if self.subset in data_subset:
master_data["subset"] = self.subset + str(
hero_data["subset"] = self.subset + str(
self.track_index)
# in case track name and subset name is the same then add
if self.subset_name == self.track_name:
master_data["subset"] = self.subset
hero_data["subset"] = self.subset
# assing data to return hierarchy data to tag
tag_hierarchy_data = master_data
tag_hierarchy_data = hero_data
# add data to return data dict
self.tag_data.update(tag_hierarchy_data)
if master_layer and self.review_layer:
# add uuid to tag data
self.tag_data["uuid"] = str(uuid.uuid4())
# add review track only to hero track
if hero_track and self.review_layer:
self.tag_data.update({"reviewTrack": self.review_layer})
def _solve_tag_hierarchy_data(self, hierarchy_formating_data):
""" Solve tag data from hierarchy data and templates. """
# fill up clip name and hierarchy keys

View file

@ -117,7 +117,7 @@ class CreateShotClip(resolve.Creator):
"vSyncTrack": {
"value": gui_tracks, # noqa
"type": "QComboBox",
"label": "Master track",
"label": "Hero track",
"target": "ui",
"toolTip": "Select driving track name which should be mastering all others", # noqa
"order": 1}

View file

@ -1,129 +0,0 @@
import pyblish
from openpype.hosts import resolve
# # developer reload modules
from pprint import pformat
class CollectInstances(pyblish.api.ContextPlugin):
"""Collect all Track items selection."""
order = pyblish.api.CollectorOrder - 0.59
label = "Collect Instances"
hosts = ["resolve"]
def process(self, context):
otio_timeline = context.data["otioTimeline"]
selected_timeline_items = resolve.get_current_timeline_items(
filter=True, selecting_color=resolve.publish_clip_color)
self.log.info(
"Processing enabled track items: {}".format(
len(selected_timeline_items)))
for timeline_item_data in selected_timeline_items:
data = dict()
timeline_item = timeline_item_data["clip"]["item"]
# get openpype tag data
tag_data = resolve.get_timeline_item_pype_tag(timeline_item)
self.log.debug(f"__ tag_data: {pformat(tag_data)}")
if not tag_data:
continue
if tag_data.get("id") != "pyblish.avalon.instance":
continue
media_pool_item = timeline_item.GetMediaPoolItem()
clip_property = media_pool_item.GetClipProperty()
self.log.debug(f"clip_property: {clip_property}")
# add tag data to instance data
data.update({
k: v for k, v in tag_data.items()
if k not in ("id", "applieswhole", "label")
})
asset = tag_data["asset"]
subset = tag_data["subset"]
# insert family into families
family = tag_data["family"]
families = [str(f) for f in tag_data["families"]]
families.insert(0, str(family))
data.update({
"name": "{} {} {}".format(asset, subset, families),
"asset": asset,
"item": timeline_item,
"families": families,
"publish": resolve.get_publish_attribute(timeline_item),
"fps": context.data["fps"]
})
# otio clip data
otio_data = resolve.get_otio_clip_instance_data(
otio_timeline, timeline_item_data) or {}
data.update(otio_data)
# add resolution
self.get_resolution_to_data(data, context)
# create instance
instance = context.create_instance(**data)
# create shot instance for shot attributes create/update
self.create_shot_instance(context, timeline_item, **data)
self.log.info("Creating instance: {}".format(instance))
self.log.debug(
"_ instance.data: {}".format(pformat(instance.data)))
def get_resolution_to_data(self, data, context):
assert data.get("otioClip"), "Missing `otioClip` data"
# solve source resolution option
if data.get("sourceResolution", None):
otio_clip_metadata = data[
"otioClip"].media_reference.metadata
data.update({
"resolutionWidth": otio_clip_metadata["width"],
"resolutionHeight": otio_clip_metadata["height"],
"pixelAspect": otio_clip_metadata["pixelAspect"]
})
else:
otio_tl_metadata = context.data["otioTimeline"].metadata
data.update({
"resolutionWidth": otio_tl_metadata["width"],
"resolutionHeight": otio_tl_metadata["height"],
"pixelAspect": otio_tl_metadata["pixelAspect"]
})
def create_shot_instance(self, context, timeline_item, **data):
master_layer = data.get("masterLayer")
hierarchy_data = data.get("hierarchyData")
if not master_layer:
return
if not hierarchy_data:
return
asset = data["asset"]
subset = "shotMain"
# insert family into families
family = "shot"
data.update({
"name": "{} {} {}".format(asset, subset, family),
"subset": subset,
"asset": asset,
"family": family,
"families": [],
"publish": resolve.get_publish_attribute(timeline_item)
})
context.create_instance(**data)

View file

@ -1,54 +0,0 @@
import pyblish.api
from openpype.hosts import resolve
from avalon import api as avalon
from pprint import pformat
# dev
from importlib import reload
from openpype.hosts.resolve.otio import davinci_export
reload(davinci_export)
class CollectWorkfile(pyblish.api.ContextPlugin):
"""Inject the current working file into context"""
label = "Collect Workfile"
order = pyblish.api.CollectorOrder - 0.6
def process(self, context):
asset = avalon.Session["AVALON_ASSET"]
subset = "workfile"
project = resolve.get_current_project()
fps = project.GetSetting("timelineFrameRate")
active_timeline = resolve.get_current_timeline()
video_tracks = resolve.get_video_track_names()
# adding otio timeline to context
otio_timeline = davinci_export.create_otio_timeline(project)
instance_data = {
"name": "{}_{}".format(asset, subset),
"asset": asset,
"subset": "{}{}".format(asset, subset.capitalize()),
"item": project,
"family": "workfile"
}
# create instance with workfile
instance = context.create_instance(**instance_data)
# update context with main project attributes
context_data = {
"activeProject": project,
"otioTimeline": otio_timeline,
"videoTracks": video_tracks,
"currentFile": project.GetName(),
"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)))

View file

@ -58,9 +58,8 @@ def _close_window(event):
def _export_button(event):
pm = resolve.GetProjectManager()
project = pm.GetCurrentProject()
fps = project.GetSetting("timelineFrameRate")
timeline = project.GetCurrentTimeline()
otio_timeline = otio_export.create_otio_timeline(timeline, fps)
otio_timeline = otio_export.create_otio_timeline(project)
otio_path = os.path.join(
itm["exportfilebttn"].Text,
timeline.GetName() + ".otio")