Merge branch 'develop' into feature/OP-3926_gpu-cache

# Conflicts:
#	website/docs/admin_hosts_maya.md
This commit is contained in:
Toke Stuart Jepsen 2023-03-29 10:26:50 +01:00
commit cfb9293348
125 changed files with 3784 additions and 2005 deletions

View file

@ -26,6 +26,7 @@ class CreateReview(plugin.Creator):
"alpha cut"
]
useMayaTimeline = True
panZoom = False
def __init__(self, *args, **kwargs):
super(CreateReview, self).__init__(*args, **kwargs)
@ -45,5 +46,6 @@ class CreateReview(plugin.Creator):
data["keepImages"] = self.keepImages
data["imagePlane"] = self.imagePlane
data["transparency"] = self.transparency
data["panZoom"] = self.panZoom
self.data = data

View file

@ -79,6 +79,8 @@ class CollectReview(pyblish.api.InstancePlugin):
data['review_width'] = instance.data['review_width']
data['review_height'] = instance.data['review_height']
data["isolate"] = instance.data["isolate"]
data["panZoom"] = instance.data.get("panZoom", False)
data["panel"] = instance.data["panel"]
cmds.setAttr(str(instance) + '.active', 1)
self.log.debug('data {}'.format(instance.context[i].data))
instance.context[i].data.update(data)

View file

@ -30,36 +30,6 @@ def _has_arnold():
return False
def escape_space(path):
"""Ensure path is enclosed by quotes to allow paths with spaces"""
return '"{}"'.format(path) if " " in path else path
def get_ocio_config_path(profile_folder):
"""Path to OpenPype vendorized OCIO.
Vendorized OCIO config file path is grabbed from the specific path
hierarchy specified below.
"{OPENPYPE_ROOT}/vendor/OpenColorIO-Configs/{profile_folder}/config.ocio"
Args:
profile_folder (str): Name of folder to grab config file from.
Returns:
str: Path to vendorized config file.
"""
return os.path.join(
os.environ["OPENPYPE_ROOT"],
"vendor",
"bin",
"ocioconfig",
"OpenColorIOConfigs",
profile_folder,
"config.ocio"
)
def find_paths_by_hash(texture_hash):
"""Find the texture hash key in the dictionary.

View file

@ -1,5 +1,6 @@
import os
import json
import contextlib
import clique
import capture
@ -11,6 +12,16 @@ from maya import cmds
import pymel.core as pm
@contextlib.contextmanager
def panel_camera(panel, camera):
original_camera = cmds.modelPanel(panel, query=True, camera=True)
try:
cmds.modelPanel(panel, edit=True, camera=camera)
yield
finally:
cmds.modelPanel(panel, edit=True, camera=original_camera)
class ExtractPlayblast(publish.Extractor):
"""Extract viewport playblast.
@ -25,6 +36,16 @@ class ExtractPlayblast(publish.Extractor):
optional = True
capture_preset = {}
def _capture(self, preset):
self.log.info(
"Using preset:\n{}".format(
json.dumps(preset, sort_keys=True, indent=4)
)
)
path = capture.capture(log=self.log, **preset)
self.log.debug("playblast path {}".format(path))
def process(self, instance):
self.log.info("Extracting capture..")
@ -43,7 +64,7 @@ class ExtractPlayblast(publish.Extractor):
self.log.info("start: {}, end: {}".format(start, end))
# get cameras
camera = instance.data['review_camera']
camera = instance.data["review_camera"]
preset = lib.load_capture_preset(data=self.capture_preset)
# Grab capture presets from the project settings
@ -57,23 +78,23 @@ class ExtractPlayblast(publish.Extractor):
asset_height = asset_data.get("resolutionHeight")
review_instance_width = instance.data.get("review_width")
review_instance_height = instance.data.get("review_height")
preset['camera'] = camera
preset["camera"] = camera
# Tests if project resolution is set,
# if it is a value other than zero, that value is
# used, if not then the asset resolution is
# used
if review_instance_width and review_instance_height:
preset['width'] = review_instance_width
preset['height'] = review_instance_height
preset["width"] = review_instance_width
preset["height"] = review_instance_height
elif width_preset and height_preset:
preset['width'] = width_preset
preset['height'] = height_preset
preset["width"] = width_preset
preset["height"] = height_preset
elif asset_width and asset_height:
preset['width'] = asset_width
preset['height'] = asset_height
preset['start_frame'] = start
preset['end_frame'] = end
preset["width"] = asset_width
preset["height"] = asset_height
preset["start_frame"] = start
preset["end_frame"] = end
# Enforce persisting camera depth of field
camera_options = preset.setdefault("camera_options", {})
@ -86,8 +107,8 @@ class ExtractPlayblast(publish.Extractor):
self.log.info("Outputting images to %s" % path)
preset['filename'] = path
preset['overwrite'] = True
preset["filename"] = path
preset["overwrite"] = True
pm.refresh(f=True)
@ -114,7 +135,8 @@ class ExtractPlayblast(publish.Extractor):
# Disable Pan/Zoom.
pan_zoom = cmds.getAttr("{}.panZoomEnabled".format(preset["camera"]))
cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), False)
preset.pop("pan_zoom", None)
preset["camera_options"]["panZoomEnabled"] = instance.data["panZoom"]
# Need to explicitly enable some viewport changes so the viewport is
# refreshed ahead of playblasting.
@ -136,30 +158,39 @@ class ExtractPlayblast(publish.Extractor):
)
override_viewport_options = (
capture_presets['Viewport Options']['override_viewport_options']
capture_presets["Viewport Options"]["override_viewport_options"]
)
with lib.maintained_time():
filename = preset.get("filename", "%TEMP%")
# Force viewer to False in call to capture because we have our own
# viewer opening call to allow a signal to trigger between
# playblast and viewer
preset['viewer'] = False
# Force viewer to False in call to capture because we have our own
# viewer opening call to allow a signal to trigger between
# playblast and viewer
preset["viewer"] = False
# Update preset with current panel setting
# if override_viewport_options is turned off
if not override_viewport_options:
panel_preset = capture.parse_view(instance.data["panel"])
panel_preset.pop("camera")
preset.update(panel_preset)
# Update preset with current panel setting
# if override_viewport_options is turned off
if not override_viewport_options:
panel_preset = capture.parse_view(instance.data["panel"])
panel_preset.pop("camera")
preset.update(panel_preset)
self.log.info(
"Using preset:\n{}".format(
json.dumps(preset, sort_keys=True, indent=4)
# Need to ensure Python 2 compatibility.
# TODO: Remove once dropping Python 2.
if getattr(contextlib, "nested", None):
# Python 3 compatibility.
with contextlib.nested(
lib.maintained_time(),
panel_camera(instance.data["panel"], preset["camera"])
):
self._capture(preset)
else:
# Python 2 compatibility.
with contextlib.ExitStack() as stack:
stack.enter_context(lib.maintained_time())
stack.enter_context(
panel_camera(instance.data["panel"], preset["camera"])
)
)
path = capture.capture(log=self.log, **preset)
self._capture(preset)
# Restoring viewport options.
if viewport_defaults:
@ -169,18 +200,17 @@ class ExtractPlayblast(publish.Extractor):
cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), pan_zoom)
self.log.debug("playblast path {}".format(path))
collected_files = os.listdir(stagingdir)
patterns = [clique.PATTERNS["frames"]]
collections, remainder = clique.assemble(collected_files,
minimum_items=1,
patterns=patterns)
filename = preset.get("filename", "%TEMP%")
self.log.debug("filename {}".format(filename))
frame_collection = None
for collection in collections:
filebase = collection.format('{head}').rstrip(".")
filebase = collection.format("{head}").rstrip(".")
self.log.debug("collection head {}".format(filebase))
if filebase in filename:
frame_collection = collection
@ -204,15 +234,15 @@ class ExtractPlayblast(publish.Extractor):
collected_files = collected_files[0]
representation = {
'name': 'png',
'ext': 'png',
'files': collected_files,
"name": self.capture_preset["Codec"]["compression"],
"ext": self.capture_preset["Codec"]["compression"],
"files": collected_files,
"stagingDir": stagingdir,
"frameStart": start,
"frameEnd": end,
'fps': fps,
'preview': True,
'tags': tags,
'camera_name': camera_node_name
"fps": fps,
"preview": True,
"tags": tags,
"camera_name": camera_node_name
}
instance.data["representations"].append(representation)

View file

@ -26,28 +26,28 @@ class ExtractThumbnail(publish.Extractor):
def process(self, instance):
self.log.info("Extracting capture..")
camera = instance.data['review_camera']
camera = instance.data["review_camera"]
capture_preset = (
instance.context.data["project_settings"]['maya']['publish']['ExtractPlayblast']['capture_preset']
)
maya_setting = instance.context.data["project_settings"]["maya"]
plugin_setting = maya_setting["publish"]["ExtractPlayblast"]
capture_preset = plugin_setting["capture_preset"]
override_viewport_options = (
capture_preset['Viewport Options']['override_viewport_options']
capture_preset["Viewport Options"]["override_viewport_options"]
)
try:
preset = lib.load_capture_preset(data=capture_preset)
except KeyError as ke:
self.log.error('Error loading capture presets: {}'.format(str(ke)))
self.log.error("Error loading capture presets: {}".format(str(ke)))
preset = {}
self.log.info('Using viewport preset: {}'.format(preset))
self.log.info("Using viewport preset: {}".format(preset))
# preset["off_screen"] = False
preset['camera'] = camera
preset['start_frame'] = instance.data["frameStart"]
preset['end_frame'] = instance.data["frameStart"]
preset['camera_options'] = {
preset["camera"] = camera
preset["start_frame"] = instance.data["frameStart"]
preset["end_frame"] = instance.data["frameStart"]
preset["camera_options"] = {
"displayGateMask": False,
"displayResolution": False,
"displayFilmGate": False,
@ -74,14 +74,14 @@ class ExtractThumbnail(publish.Extractor):
# used, if not then the asset resolution is
# used
if review_instance_width and review_instance_height:
preset['width'] = review_instance_width
preset['height'] = review_instance_height
preset["width"] = review_instance_width
preset["height"] = review_instance_height
elif width_preset and height_preset:
preset['width'] = width_preset
preset['height'] = height_preset
preset["width"] = width_preset
preset["height"] = height_preset
elif asset_width and asset_height:
preset['width'] = asset_width
preset['height'] = asset_height
preset["width"] = asset_width
preset["height"] = asset_height
# Create temp directory for thumbnail
# - this is to avoid "override" of source file
@ -96,8 +96,8 @@ class ExtractThumbnail(publish.Extractor):
self.log.info("Outputting images to %s" % path)
preset['filename'] = path
preset['overwrite'] = True
preset["filename"] = path
preset["overwrite"] = True
pm.refresh(f=True)
@ -123,14 +123,14 @@ class ExtractThumbnail(publish.Extractor):
preset["viewport_options"] = {"imagePlane": image_plane}
# Disable Pan/Zoom.
pan_zoom = cmds.getAttr("{}.panZoomEnabled".format(preset["camera"]))
cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), False)
preset.pop("pan_zoom", None)
preset["camera_options"]["panZoomEnabled"] = instance.data["panZoom"]
with lib.maintained_time():
# Force viewer to False in call to capture because we have our own
# viewer opening call to allow a signal to trigger between
# playblast and viewer
preset['viewer'] = False
preset["viewer"] = False
# Update preset with current panel setting
# if override_viewport_options is turned off
@ -145,17 +145,15 @@ class ExtractThumbnail(publish.Extractor):
_, thumbnail = os.path.split(playblast)
cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), pan_zoom)
self.log.info("file list {}".format(thumbnail))
if "representations" not in instance.data:
instance.data["representations"] = []
representation = {
'name': 'thumbnail',
'ext': 'jpg',
'files': thumbnail,
"name": "thumbnail",
"ext": "jpg",
"files": thumbnail,
"stagingDir": dst_staging,
"thumbnail": True
}

View file

@ -80,21 +80,7 @@ def get_all_asset_nodes():
Returns:
list: list of dictionaries
"""
host = registered_host()
nodes = []
for container in host.ls():
# We are not interested in looks but assets!
if container["loader"] == "LookLoader":
continue
# Gather all information
container_name = container["objectName"]
nodes += lib.get_container_members(container_name)
nodes = list(set(nodes))
return nodes
return cmds.ls(dag=True, noIntermediate=True, long=True)
def create_asset_id_hash(nodes):