Merge pull request #15 from pypeclub/bug/PYPE-767_maya_review_handles

PYPE-767 - unify handles behaviour across maya publishing
This commit is contained in:
Milan Kolar 2020-03-24 17:21:43 +01:00 committed by GitHub
commit a0b609fcf4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 157 additions and 79 deletions

View file

@ -15,7 +15,7 @@ import pyblish.api
class CollectAvalonEntities(pyblish.api.ContextPlugin):
"""Collect Anatomy into Context"""
order = pyblish.api.CollectorOrder
order = pyblish.api.CollectorOrder - 0.02
label = "Collect Avalon Entities"
def process(self, context):
@ -47,7 +47,16 @@ class CollectAvalonEntities(pyblish.api.ContextPlugin):
context.data["assetEntity"] = asset_entity
data = asset_entity['data']
context.data["frameStart"] = data.get("frameStart")
context.data["frameEnd"] = data.get("frameEnd")
handles = int(data.get("handles") or 0)
context.data["handles"] = handles
context.data["handleStart"] = int(data.get("handleStart", handles))
context.data["handleEnd"] = int(data.get("handleEnd", handles))
frame_start_h = data.get("frameStart") - context.data["handleStart"]
frame_end_h = data.get("frameEnd") + context.data["handleEnd"]
context.data["frameStartHandle"] = frame_start_h
context.data["frameEndHandle"] = frame_end_h

View file

@ -13,7 +13,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin):
`PYPE_PUBLISH_DATA`. Those files _MUST_ share same context.
"""
order = pyblish.api.CollectorOrder - 0.0001
order = pyblish.api.CollectorOrder - 0.1
targets = ["filesequence"]
label = "Collect rendered frames"

View file

@ -1,16 +0,0 @@
from maya import cmds
import pyblish.api
class CollectMayaCurrentFile(pyblish.api.ContextPlugin):
"""Inject the current working file into context"""
order = pyblish.api.CollectorOrder - 0.5
label = "Maya Current File"
hosts = ['maya']
def process(self, context):
"""Inject the current working file"""
current_file = cmds.file(query=True, sceneName=True)
context.data['currentFile'] = current_file

View file

@ -1,6 +1,7 @@
from maya import cmds
import pyblish.api
import json
class CollectInstances(pyblish.api.ContextPlugin):
@ -32,6 +33,13 @@ class CollectInstances(pyblish.api.ContextPlugin):
objectset = cmds.ls("*.id", long=True, type="objectSet",
recursive=True, objectsOnly=True)
ctx_frame_start = context.data['frameStart']
ctx_frame_end = context.data['frameEnd']
ctx_handle_start = context.data['handleStart']
ctx_handle_end = context.data['handleEnd']
ctx_frame_start_handle = context.data['frameStartHandle']
ctx_frame_end_handle = context.data['frameEndHandle']
context.data['objectsets'] = objectset
for objset in objectset:
@ -108,14 +116,36 @@ class CollectInstances(pyblish.api.ContextPlugin):
label = "{0} ({1})".format(name,
data["asset"])
if "handles" in data:
data["handleStart"] = data["handles"]
data["handleEnd"] = data["handles"]
# Append start frame and end frame to label if present
if "frameStart" and "frameEnd" in data:
data["frameStartHandle"] = data["frameStart"] - data["handleStart"]
data["frameEndHandle"] = data["frameEnd"] + data["handleEnd"]
# if frame range on maya set is the same as full shot range
# adjust the values to match the asset data
if (ctx_frame_start_handle == data["frameStart"]
and ctx_frame_end_handle == data["frameEnd"]): # noqa: W503, E501
data["frameStartHandle"] = ctx_frame_start_handle
data["frameEndHandle"] = ctx_frame_end_handle
data["frameStart"] = ctx_frame_start
data["frameEnd"] = ctx_frame_end
data["handleStart"] = ctx_handle_start
data["handleEnd"] = ctx_handle_end
# if there are user values on start and end frame not matching
# the asset, use them
else:
if "handles" in data:
data["handleStart"] = data["handles"]
data["handleEnd"] = data["handles"]
else:
data["handleStart"] = 0
data["handleEnd"] = 0
data["frameStartHandle"] = data["frameStart"] - data["handleStart"] # noqa: E501
data["frameEndHandle"] = data["frameEnd"] + data["handleEnd"] # noqa: E501
if "handles" in data:
data.pop('handles')
label += " [{0}-{1}]".format(int(data["frameStartHandle"]),
int(data["frameEndHandle"]))
@ -127,7 +157,8 @@ class CollectInstances(pyblish.api.ContextPlugin):
# Produce diagnostic message for any graphical
# user interface interested in visualising it.
self.log.info("Found: \"%s\" " % instance.data["name"])
self.log.debug("DATA: \"%s\" " % instance.data)
self.log.debug(
"DATA: {} ".format(json.dumps(instance.data, indent=4)))
def sort_by_family(instance):
"""Sort by family"""

View file

@ -41,6 +41,7 @@ import re
import os
import types
import six
import json
from abc import ABCMeta, abstractmethod
from maya import cmds
@ -202,6 +203,28 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
full_paths.append(full_path)
aov_dict["beauty"] = full_paths
frame_start_render = int(self.get_render_attribute(
"startFrame", layer=layer_name))
frame_end_render = int(self.get_render_attribute(
"endFrame", layer=layer_name))
if (int(context.data['frameStartHandle']) == frame_start_render
and int(context.data['frameEndHandle']) == frame_end_render): # noqa: W503, E501
handle_start = context.data['handleStart']
handle_end = context.data['handleEnd']
frame_start = context.data['frameStart']
frame_end = context.data['frameEnd']
frame_start_handle = context.data['frameStartHandle']
frame_end_handle = context.data['frameEndHandle']
else:
handle_start = 0
handle_end = 0
frame_start = frame_start_render
frame_end = frame_end_render
frame_start_handle = frame_start_render
frame_end_handle = frame_end_render
full_exp_files.append(aov_dict)
self.log.info(full_exp_files)
self.log.info("collecting layer: {}".format(layer_name))
@ -211,24 +234,18 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
"attachTo": attachTo,
"setMembers": layer_name,
"publish": True,
"frameStart": int(
context.data["assetEntity"]['data']['frameStart']),
"frameEnd": int(
context.data["assetEntity"]['data']['frameEnd']),
"frameStartHandle": int(
self.get_render_attribute("startFrame", layer=layer_name)),
"frameEndHandle": int(
self.get_render_attribute("endFrame", layer=layer_name)),
"handleStart": handle_start,
"handleEnd": handle_end,
"frameStart": frame_start,
"frameEnd": frame_end,
"frameStartHandle": frame_start_handle,
"frameEndHandle": frame_end_handle,
"byFrameStep": int(
self.get_render_attribute("byFrameStep",
layer=layer_name)),
"renderer": self.get_render_attribute("currentRenderer",
layer=layer_name),
"handleStart": int(
context.data["assetEntity"]['data']['handleStart']),
"handleEnd": int(
context.data["assetEntity"]['data']['handleEnd']),
# instance subset
"family": "renderlayer",
"families": ["renderlayer"],
@ -271,7 +288,7 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
instance = context.create_instance(expected_layer_name)
instance.data["label"] = label
instance.data.update(data)
pass
self.log.debug("data: {}".format(json.dumps(data, indent=4)))
def parse_options(self, render_globals):
"""Get all overrides with a value, skip those without
@ -489,7 +506,7 @@ class AExpectedFiles:
expected_files.append(
'{}.{}.{}'.format(file_prefix,
str(frame).rjust(
layer_data["padding"], "0"),
layer_data["padding"], "0"),
layer_data["defaultExt"]))
return expected_files
@ -625,7 +642,7 @@ class ExpectedFilesArnold(AExpectedFiles):
enabled_aovs = []
try:
if not (cmds.getAttr('defaultArnoldRenderOptions.aovMode')
and not cmds.getAttr('defaultArnoldDriver.mergeAOVs')):
and not cmds.getAttr('defaultArnoldDriver.mergeAOVs')): # noqa: W503, E501
# AOVs are merged in mutli-channel file
return enabled_aovs
except ValueError:
@ -746,10 +763,7 @@ class ExpectedFilesVray(AExpectedFiles):
if enabled:
# todo: find how vray set format for AOVs
enabled_aovs.append(
(
self._get_vray_aov_name(aov),
default_ext)
)
(self._get_vray_aov_name(aov), default_ext))
return enabled_aovs
def _get_vray_aov_name(self, node):

View file

@ -9,13 +9,14 @@ from pype.maya import lib
class CollectMayaScene(pyblish.api.ContextPlugin):
"""Inject the current working file into context"""
order = pyblish.api.CollectorOrder - 0.1
order = pyblish.api.CollectorOrder - 0.01
label = "Maya Workfile"
hosts = ['maya']
def process(self, context):
"""Inject the current working file"""
current_file = context.data['currentFile']
current_file = cmds.file(query=True, sceneName=True)
context.data['currentFile'] = current_file
folder, file = os.path.split(current_file)
filename, ext = os.path.splitext(file)
@ -24,9 +25,6 @@ class CollectMayaScene(pyblish.api.ContextPlugin):
data = {}
for key, value in lib.collect_animation_data().items():
data[key] = value
# create instance
instance = context.create_instance(name=filename)
subset = 'workfile' + task.capitalize()
@ -38,7 +36,11 @@ class CollectMayaScene(pyblish.api.ContextPlugin):
"publish": True,
"family": 'workfile',
"families": ['workfile'],
"setMembers": [current_file]
"setMembers": [current_file],
"frameStart": context.data['frameStart'],
"frameEnd": context.data['frameEnd'],
"handleStart": context.data['handleStart'],
"handleEnd": context.data['handleEnd']
})
data['representations'] = [{

View file

@ -25,12 +25,8 @@ class ExtractAlembic(pype.api.Extractor):
nodes = instance[:]
# Collect the start and end including handles
start = instance.data.get("frameStart", 1)
end = instance.data.get("frameEnd", 1)
handles = instance.data.get("handles", 0)
if handles:
start -= handles
end += handles
start = float(instance.data.get("frameStartHandle", 1))
end = float(instance.data.get("frameEndHandle", 1))
attrs = instance.data.get("attr", "").split(";")
attrs = [value for value in attrs if value.strip()]

View file

@ -1,18 +1,19 @@
import pyblish.api
import pype.api
from maya import cmds
class ValidateFrameRange(pyblish.api.InstancePlugin):
"""Valides the frame ranges.
Checks the `startFrame`, `endFrame` and `handles` data.
This does NOT ensure there's actual data present.
This is optional validator checking if the frame range on instance
matches the one of asset. It also validate render frame range of render
layers
This validates:
- `startFrame` is lower than or equal to the `endFrame`.
- must have both the `startFrame` and `endFrame` data.
- The `handles` value is not lower than zero.
Repair action will change everything to match asset.
This can be turned off by artist to allow custom ranges.
"""
label = "Validate Frame Range"
@ -21,25 +22,66 @@ class ValidateFrameRange(pyblish.api.InstancePlugin):
"pointcache",
"camera",
"renderlayer",
"colorbleed.vrayproxy"]
"review",
"yeticache"]
optional = True
actions = [pype.api.RepairAction]
def process(self, instance):
context = instance.context
start = instance.data.get("frameStart", None)
end = instance.data.get("frameEnd", None)
handles = instance.data.get("handles", None)
frame_start_handle = int(context.data.get("frameStartHandle"))
frame_end_handle = int(context.data.get("frameEndHandle"))
handles = int(context.data.get("handles"))
handle_start = int(context.data.get("handleStart"))
handle_end = int(context.data.get("handleEnd"))
frame_start = int(context.data.get("frameStart"))
frame_end = int(context.data.get("frameEnd"))
# Check if any of the values are present
if any(value is None for value in [start, end]):
raise ValueError("No time values for this instance. "
"(Missing `startFrame` or `endFrame`)")
inst_start = int(instance.data.get("frameStartHandle"))
inst_end = int(instance.data.get("frameEndHandle"))
self.log.info("Comparing start (%s) and end (%s)" % (start, end))
if start > end:
raise RuntimeError("The start frame is a higher value "
"than the end frame: "
"{0}>{1}".format(start, end))
# basic sanity checks
assert frame_start_handle <= frame_end_handle, (
"start frame is lower then end frame")
if handles is not None:
if handles < 0.0:
raise RuntimeError("Handles are set to a negative value")
assert handles >= 0, ("handles cannot have negative values")
# compare with data on instance
errors = []
if(inst_start != frame_start_handle):
errors.append("Instance start frame [ {} ] doesn't "
"match the one set on instance [ {} ]: "
"{}/{}/{}/{} (handle/start/end/handle)".format(
inst_start,
frame_start_handle,
handle_start, frame_start, frame_end, handle_end
))
if(inst_end != frame_end_handle):
errors.append("Instance end frame [ {} ] doesn't "
"match the one set on instance [ {} ]: "
"{}/{}/{}/{} (handle/start/end/handle)".format(
inst_end,
frame_end_handle,
handle_start, frame_start, frame_end, handle_end
))
for e in errors:
self.log.error(e)
assert len(errors) == 0, ("Frame range settings are incorrect")
@classmethod
def repair(cls, instance):
"""
Repair instance container to match asset data.
"""
cmds.setAttr(
"{}.frameStart".format(instance.data["name"]),
instance.context.data.get("frameStartHandle"))
cmds.setAttr(
"{}.frameEnd".format(instance.data["name"]),
instance.context.data.get("frameEndHandle"))