Merge pull request #2445 from BigRoy/maya_py3_compatibility

This commit is contained in:
Milan Kolar 2022-02-25 16:38:40 +01:00 committed by GitHub
commit 8b58c2cc9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 177 additions and 56 deletions

View file

@ -5,7 +5,7 @@ import logging
from functools import partial
import maya.cmds as mc
import maya.cmds as cmds
import maya.mel as mel
from openpype.api import resources
@ -30,9 +30,9 @@ def override_component_mask_commands():
log.info("Installing override_component_mask_commands..")
# Get all object mask buttons
buttons = mc.formLayout("objectMaskIcons",
query=True,
childArray=True)
buttons = cmds.formLayout("objectMaskIcons",
query=True,
childArray=True)
# Skip the triangle list item
buttons = [btn for btn in buttons if btn != "objPickMenuLayout"]
@ -43,14 +43,14 @@ def override_component_mask_commands():
# toggle the others based on whether any of the buttons
# was remaining active after the toggle, if not then
# enable all
if mc.getModifiers() == 4: # = CTRL
if cmds.getModifiers() == 4: # = CTRL
state = True
active = [mc.iconTextCheckBox(btn, query=True, value=True) for btn
in buttons]
active = [cmds.iconTextCheckBox(btn, query=True, value=True)
for btn in buttons]
if any(active):
mc.selectType(allObjects=False)
cmds.selectType(allObjects=False)
else:
mc.selectType(allObjects=True)
cmds.selectType(allObjects=True)
# Replace #1 with the current button state
cmd = raw_command.replace(" #1", " {}".format(int(state)))
@ -63,13 +63,13 @@ def override_component_mask_commands():
# try to implement the fix. (This also allows us to
# "uninstall" the behavior later)
if btn not in COMPONENT_MASK_ORIGINAL:
original = mc.iconTextCheckBox(btn, query=True, cc=True)
original = cmds.iconTextCheckBox(btn, query=True, cc=True)
COMPONENT_MASK_ORIGINAL[btn] = original
# Assign the special callback
original = COMPONENT_MASK_ORIGINAL[btn]
new_fn = partial(on_changed_callback, original)
mc.iconTextCheckBox(btn, edit=True, cc=new_fn)
cmds.iconTextCheckBox(btn, edit=True, cc=new_fn)
def override_toolbox_ui():
@ -78,25 +78,36 @@ def override_toolbox_ui():
parent_widget = get_main_window()
# Ensure the maya web icon on toolbox exists
web_button = "ToolBox|MainToolboxLayout|mayaWebButton"
if not mc.iconTextButton(web_button, query=True, exists=True):
button_names = [
# Maya 2022.1+ with maya.cmds.iconTextStaticLabel
"ToolBox|MainToolboxLayout|mayaHomeToolboxButton",
# Older with maya.cmds.iconTextButton
"ToolBox|MainToolboxLayout|mayaWebButton"
]
for name in button_names:
if cmds.control(name, query=True, exists=True):
web_button = name
break
else:
# Button does not exist
log.warning("Can't find Maya Home/Web button to override toolbox ui..")
return
mc.iconTextButton(web_button, edit=True, visible=False)
cmds.control(web_button, edit=True, visible=False)
# real = 32, but 36 with padding - according to toolbox mel script
icon_size = 36
parent = web_button.rsplit("|", 1)[0]
# Ensure the parent is a formLayout
if not mc.objectTypeUI(parent) == "formLayout":
if not cmds.objectTypeUI(parent) == "formLayout":
return
# Create our controls
controls = []
controls.append(
mc.iconTextButton(
cmds.iconTextButton(
"pype_toolbox_lookmanager",
annotation="Look Manager",
label="Look Manager",
@ -109,7 +120,7 @@ def override_toolbox_ui():
)
controls.append(
mc.iconTextButton(
cmds.iconTextButton(
"pype_toolbox_workfiles",
annotation="Work Files",
label="Work Files",
@ -124,7 +135,7 @@ def override_toolbox_ui():
)
controls.append(
mc.iconTextButton(
cmds.iconTextButton(
"pype_toolbox_loader",
annotation="Loader",
label="Loader",
@ -139,7 +150,7 @@ def override_toolbox_ui():
)
controls.append(
mc.iconTextButton(
cmds.iconTextButton(
"pype_toolbox_manager",
annotation="Inventory",
label="Inventory",
@ -159,7 +170,7 @@ def override_toolbox_ui():
for i, control in enumerate(controls):
previous = controls[i - 1] if i > 0 else web_button
mc.formLayout(parent, edit=True,
attachControl=[control, "bottom", 0, previous],
attachForm=([control, "left", 1],
[control, "right", 1]))
cmds.formLayout(parent, edit=True,
attachControl=[control, "bottom", 0, previous],
attachForm=([control, "left", 1],
[control, "right", 1]))

View file

@ -8,7 +8,6 @@ import math
import json
import logging
import itertools
import contextlib
from collections import OrderedDict, defaultdict
from math import ceil
@ -267,8 +266,10 @@ def float_round(num, places=0, direction=ceil):
def pairwise(iterable):
"""s -> (s0,s1), (s2,s3), (s4, s5), ..."""
from six.moves import zip
a = iter(iterable)
return itertools.izip(a, a)
return zip(a, a)
def export_alembic(nodes,
@ -2986,7 +2987,27 @@ def set_colorspace():
"""
project_name = os.getenv("AVALON_PROJECT")
imageio = get_anatomy_settings(project_name)["imageio"]["maya"]
root_dict = imageio["colorManagementPreference"]
# Maya 2022+ introduces new OCIO v2 color management settings that
# can override the old color managenement preferences. OpenPype has
# separate settings for both so we fall back when necessary.
use_ocio_v2 = imageio["colorManagementPreference_v2"]["enabled"]
required_maya_version = 2022
maya_version = int(cmds.about(version=True))
maya_supports_ocio_v2 = maya_version >= required_maya_version
if use_ocio_v2 and not maya_supports_ocio_v2:
# Fallback to legacy behavior with a warning
log.warning("Color Management Preference v2 is enabled but not "
"supported by current Maya version: {} (< {}). Falling "
"back to legacy settings.".format(
maya_version, required_maya_version)
)
use_ocio_v2 = False
if use_ocio_v2:
root_dict = imageio["colorManagementPreference_v2"]
else:
root_dict = imageio["colorManagementPreference"]
if not isinstance(root_dict, dict):
msg = "set_colorspace(): argument should be dictionary"
@ -2994,11 +3015,12 @@ def set_colorspace():
log.debug(">> root_dict: {}".format(root_dict))
# first enable color management
# enable color management
cmds.colorManagementPrefs(e=True, cmEnabled=True)
cmds.colorManagementPrefs(e=True, ocioRulesEnabled=True)
# second set config path
# set config path
custom_ocio_config = False
if root_dict.get("configFilePath"):
unresolved_path = root_dict["configFilePath"]
ocio_paths = unresolved_path[platform.system().lower()]
@ -3015,16 +3037,50 @@ def set_colorspace():
cmds.colorManagementPrefs(e=True, cmConfigFileEnabled=True)
log.debug("maya '{}' changed to: {}".format(
"configFilePath", resolved_path))
root_dict.pop("configFilePath")
custom_ocio_config = True
else:
cmds.colorManagementPrefs(e=True, cmConfigFileEnabled=False)
cmds.colorManagementPrefs(e=True, configFilePath="" )
cmds.colorManagementPrefs(e=True, configFilePath="")
# third set rendering space and view transform
renderSpace = root_dict["renderSpace"]
cmds.colorManagementPrefs(e=True, renderingSpaceName=renderSpace)
viewTransform = root_dict["viewTransform"]
cmds.colorManagementPrefs(e=True, viewTransformName=viewTransform)
# If no custom OCIO config file was set we make sure that Maya 2022+
# either chooses between Maya's newer default v2 or legacy config based
# on OpenPype setting to use ocio v2 or not.
if maya_supports_ocio_v2 and not custom_ocio_config:
if use_ocio_v2:
# Use Maya 2022+ default OCIO v2 config
log.info("Setting default Maya OCIO v2 config")
cmds.colorManagementPrefs(edit=True, configFilePath="")
else:
# Set the Maya default config file path
log.info("Setting default Maya OCIO v1 legacy config")
cmds.colorManagementPrefs(edit=True, configFilePath="legacy")
# set color spaces for rendering space and view transforms
def _colormanage(**kwargs):
"""Wrapper around `cmds.colorManagementPrefs`.
This logs errors instead of raising an error so color management
settings get applied as much as possible.
"""
assert len(kwargs) == 1, "Must receive one keyword argument"
try:
cmds.colorManagementPrefs(edit=True, **kwargs)
log.debug("Setting Color Management Preference: {}".format(kwargs))
except RuntimeError as exc:
log.error(exc)
if use_ocio_v2:
_colormanage(renderingSpaceName=root_dict["renderSpace"])
_colormanage(displayName=root_dict["displayName"])
_colormanage(viewName=root_dict["viewName"])
else:
_colormanage(renderingSpaceName=root_dict["renderSpace"])
if maya_supports_ocio_v2:
_colormanage(viewName=root_dict["viewTransform"])
_colormanage(displayName="legacy")
else:
_colormanage(viewTransformName=root_dict["viewTransform"])
@contextlib.contextmanager

View file

@ -253,7 +253,7 @@ class CreateRender(plugin.Creator):
# get pools
pool_names = []
self.server_aliases = self.deadline_servers.keys()
self.server_aliases = list(self.deadline_servers.keys())
self.data["deadlineServers"] = self.server_aliases
self.data["suspendPublishJob"] = False
self.data["review"] = True
@ -286,15 +286,12 @@ class CreateRender(plugin.Creator):
raise RuntimeError("Both Deadline and Muster are enabled")
if deadline_enabled:
# if default server is not between selected, use first one for
# initial list of pools.
try:
deadline_url = self.deadline_servers["default"]
except KeyError:
deadline_url = [
self.deadline_servers[k]
for k in self.deadline_servers.keys()
][0]
# if 'default' server is not between selected,
# use first one for initial list of pools.
deadline_url = next(iter(self.deadline_servers.values()))
pool_names = self._get_deadline_pools(deadline_url)

View file

@ -320,7 +320,7 @@ class CollectLook(pyblish.api.InstancePlugin):
# Collect file nodes used by shading engines (if we have any)
files = []
look_sets = sets.keys()
look_sets = list(sets.keys())
shader_attrs = [
"surfaceShader",
"volumeShader",

View file

@ -234,13 +234,14 @@ class CollectMayaRender(pyblish.api.ContextPlugin):
publish_meta_path = None
for aov in exp_files:
full_paths = []
for file in aov[aov.keys()[0]]:
aov_first_key = list(aov.keys())[0]
for file in aov[aov_first_key]:
full_path = os.path.join(workspace, default_render_file,
file)
full_path = full_path.replace("\\", "/")
full_paths.append(full_path)
publish_meta_path = os.path.dirname(full_path)
aov_dict[aov.keys()[0]] = full_paths
aov_dict[aov_first_key] = full_paths
frame_start_render = int(self.get_render_attribute(
"startFrame", layer=layer_name))

View file

@ -43,7 +43,8 @@ def grouper(iterable, n, fillvalue=None):
"""
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
from six.moves import zip_longest
return zip_longest(fillvalue=fillvalue, *args)
def unlock(plug):

View file

@ -4,6 +4,7 @@ import os
import sys
import json
import tempfile
import platform
import contextlib
import subprocess
from collections import OrderedDict
@ -62,6 +63,11 @@ def maketx(source, destination, *args):
from openpype.lib import get_oiio_tools_path
maketx_path = get_oiio_tools_path("maketx")
if platform.system().lower() == "windows":
# Ensure .exe extension
maketx_path += ".exe"
if not os.path.exists(maketx_path):
print(
"OIIO tool not found in {}".format(maketx_path))
@ -216,7 +222,7 @@ class ExtractLook(openpype.api.Extractor):
self.log.info("Extract sets (%s) ..." % _scene_type)
lookdata = instance.data["lookData"]
relationships = lookdata["relationships"]
sets = relationships.keys()
sets = list(relationships.keys())
if not sets:
self.log.info("No sets found")
return

View file

@ -110,9 +110,9 @@ class ValidateAssRelativePaths(pyblish.api.InstancePlugin):
Maya API will return a list of values, which need to be properly
handled to evaluate properly.
"""
if isinstance(attr_val, types.BooleanType):
if isinstance(attr_val, bool):
return attr_val
elif isinstance(attr_val, (types.ListType, types.GeneratorType)):
elif isinstance(attr_val, (list, types.GeneratorType)):
return any(attr_val)
else:
return bool(attr_val)

View file

@ -5,6 +5,8 @@ import math
import maya.api.OpenMaya as om
import pymel.core as pm
from six.moves import xrange
class GetOverlappingUVs(object):

View file

@ -82,9 +82,9 @@ class ValidateVrayReferencedAOVs(pyblish.api.InstancePlugin):
bool: cast Maya attribute to Pythons boolean value.
"""
if isinstance(attr_val, types.BooleanType):
if isinstance(attr_val, bool):
return attr_val
elif isinstance(attr_val, (types.ListType, types.GeneratorType)):
elif isinstance(attr_val, (list, types.GeneratorType)):
return any(attr_val)
else:
return bool(attr_val)

View file

@ -177,6 +177,17 @@
}
},
"maya": {
"colorManagementPreference_v2": {
"enabled": true,
"configFilePath": {
"windows": [],
"darwin": [],
"linux": []
},
"renderSpace": "ACEScg",
"viewName": "ACES 1.0 SDR-video",
"displayName": "sRGB"
},
"colorManagementPreference": {
"configFilePath": {
"windows": [],

View file

@ -93,7 +93,7 @@
}
},
"__dynamic_keys_labels__": {
"2022": "2022 (Testing Only)"
"2022": "2022"
}
}
},

View file

@ -377,11 +377,47 @@
"type": "dict",
"label": "Maya",
"children": [
{
"key": "colorManagementPreference_v2",
"type": "dict",
"label": "Color Management Preference v2 (Maya 2022+)",
"collapsible": true,
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Use Color Management Preference v2"
},
{
"type": "path",
"key": "configFilePath",
"label": "OCIO Config File Path",
"multiplatform": true,
"multipath": true
},
{
"type": "text",
"key": "renderSpace",
"label": "Rendering Space"
},
{
"type": "text",
"key": "displayName",
"label": "Display"
},
{
"type": "text",
"key": "viewName",
"label": "View"
}
]
},
{
"key": "colorManagementPreference",
"type": "dict",
"label": "Color Managment Preference",
"collapsible": false,
"label": "Color Management Preference (legacy)",
"collapsible": true,
"children": [
{
"type": "path",
@ -401,7 +437,7 @@
"label": "Viewer Transform"
}
]
}
}
]
},
{

@ -1 +1 @@
Subproject commit 159d2f23e4c79c04dfac57b68d2ee6ac67adec1b
Subproject commit ffe9e910f1f382e222d457d8e4a8426c41ed43ae