Merge branch 'develop' into enhancement/OP-3807_playblast_profiles

# Conflicts:
#	openpype/hosts/maya/api/lib.py
This commit is contained in:
Toke Stuart Jepsen 2023-04-13 11:40:02 +01:00
commit 4f79d7fab2
77 changed files with 1581 additions and 412 deletions

View file

@ -32,7 +32,12 @@ from openpype.pipeline import (
load_container,
registered_host,
)
from openpype.pipeline.context_tools import get_current_project_asset
from openpype.pipeline.context_tools import (
get_current_asset_name,
get_current_project_asset,
get_current_project_name,
get_current_task_name
)
from openpype.lib.profiles_filtering import filter_profiles
@ -293,15 +298,20 @@ def collect_animation_data(fps=False):
"""
# get scene values as defaults
start = cmds.playbackOptions(query=True, animationStartTime=True)
end = cmds.playbackOptions(query=True, animationEndTime=True)
frame_start = cmds.playbackOptions(query=True, minTime=True)
frame_end = cmds.playbackOptions(query=True, maxTime=True)
handle_start = cmds.playbackOptions(query=True, animationStartTime=True)
handle_end = cmds.playbackOptions(query=True, animationEndTime=True)
handle_start = frame_start - handle_start
handle_end = handle_end - frame_end
# build attributes
data = OrderedDict()
data["frameStart"] = start
data["frameEnd"] = end
data["handleStart"] = 0
data["handleEnd"] = 0
data["frameStart"] = frame_start
data["frameEnd"] = frame_end
data["handleStart"] = handle_start
data["handleEnd"] = handle_end
data["step"] = 1.0
if fps:
@ -2135,9 +2145,13 @@ def get_frame_range():
"""Get the current assets frame range and handles."""
# Set frame start/end
project_name = legacy_io.active_project()
asset_name = legacy_io.Session["AVALON_ASSET"]
project_name = get_current_project_name()
task_name = get_current_task_name()
asset_name = get_current_asset_name()
asset = get_asset_by_name(project_name, asset_name)
settings = get_project_settings(project_name)
include_handles_settings = settings["maya"]["include_handles"]
current_task = asset.get("data").get("tasks").get(task_name)
frame_start = asset["data"].get("frameStart")
frame_end = asset["data"].get("frameEnd")
@ -2149,6 +2163,26 @@ def get_frame_range():
handle_start = asset["data"].get("handleStart") or 0
handle_end = asset["data"].get("handleEnd") or 0
animation_start = frame_start
animation_end = frame_end
include_handles = include_handles_settings["include_handles_default"]
for item in include_handles_settings["per_task_type"]:
if current_task["type"] in item["task_type"]:
include_handles = item["include_handles"]
break
if include_handles:
animation_start -= int(handle_start)
animation_end += int(handle_end)
cmds.playbackOptions(
minTime=frame_start,
maxTime=frame_end,
animationStartTime=animation_start,
animationEndTime=animation_end
)
cmds.currentTime(frame_start)
return {
"frameStart": frame_start,
"frameEnd": frame_end,
@ -2167,7 +2201,6 @@ def reset_frame_range(playback=True, render=True, fps=True):
Defaults to True.
fps (bool, Optional): Whether to set scene FPS. Defaults to True.
"""
if fps:
fps = convert_to_maya_fps(
float(legacy_io.Session.get("AVALON_FPS", 25))
@ -3656,7 +3689,17 @@ def get_color_management_preferences():
# Split view and display from view_transform. view_transform comes in
# format of "{view} ({display})".
regex = re.compile(r"^(?P<view>.+) \((?P<display>.+)\)$")
if int(cmds.about(version=True)) <= 2020:
# view_transform comes in format of "{view} {display}" in 2020.
regex = re.compile(r"^(?P<view>.+) (?P<display>.+)$")
match = regex.match(data["view_transform"])
if not match:
raise ValueError(
"Unable to parse view and display from Maya view transform: '{}' "
"using regex '{}'".format(data["view_transform"], regex.pattern)
)
data.update({
"display": match.group("display"),
"view": match.group("view")

View file

@ -1,4 +1,5 @@
import os
import re
from maya import cmds
@ -12,6 +13,7 @@ from openpype.pipeline import (
AVALON_CONTAINER_ID,
Anatomy,
)
from openpype.pipeline.load import LoadError
from openpype.settings import get_project_settings
from .pipeline import containerise
from . import lib
@ -82,6 +84,44 @@ def get_reference_node_parents(ref):
return parents
def get_custom_namespace(custom_namespace):
"""Return unique namespace.
The input namespace can contain a single group
of '#' number tokens to indicate where the namespace's
unique index should go. The amount of tokens defines
the zero padding of the number, e.g ### turns into 001.
Warning: Note that a namespace will always be
prefixed with a _ if it starts with a digit
Example:
>>> get_custom_namespace("myspace_##_")
# myspace_01_
>>> get_custom_namespace("##_myspace")
# _01_myspace
>>> get_custom_namespace("myspace##")
# myspace01
"""
split = re.split("([#]+)", custom_namespace, 1)
if len(split) == 3:
base, padding, suffix = split
padding = "%0{}d".format(len(padding))
else:
base = split[0]
padding = "%02d" # default padding
suffix = ""
return lib.unique_namespace(
base,
format=padding,
prefix="_" if not base or base[0].isdigit() else "",
suffix=suffix
)
class Creator(LegacyCreator):
defaults = ['Main']
@ -143,15 +183,46 @@ class ReferenceLoader(Loader):
assert os.path.exists(self.fname), "%s does not exist." % self.fname
asset = context['asset']
subset = context['subset']
settings = get_project_settings(context['project']['name'])
custom_naming = settings['maya']['load']['reference_loader']
loaded_containers = []
count = options.get("count") or 1
for c in range(0, count):
namespace = namespace or lib.unique_namespace(
"{}_{}_".format(asset["name"], context["subset"]["name"]),
prefix="_" if asset["name"][0].isdigit() else "",
suffix="_",
if not custom_naming['namespace']:
raise LoadError("No namespace specified in "
"Maya ReferenceLoader settings")
elif not custom_naming['group_name']:
raise LoadError("No group name specified in "
"Maya ReferenceLoader settings")
formatting_data = {
"asset_name": asset['name'],
"asset_type": asset['type'],
"subset": subset['name'],
"family": (
subset['data'].get('family') or
subset['data']['families'][0]
)
}
custom_namespace = custom_naming['namespace'].format(
**formatting_data
)
custom_group_name = custom_naming['group_name'].format(
**formatting_data
)
count = options.get("count") or 1
for c in range(0, count):
namespace = get_custom_namespace(custom_namespace)
group_name = "{}:{}".format(
namespace,
custom_group_name
)
options['group_name'] = group_name
# Offset loaded subset
if "offset" in options:
@ -187,7 +258,7 @@ class ReferenceLoader(Loader):
return loaded_containers
def process_reference(self, context, name, namespace, data):
def process_reference(self, context, name, namespace, options):
"""To be implemented by subclass"""
raise NotImplementedError("Must be implemented by subclass")

View file

@ -14,7 +14,7 @@ class AbcLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
icon = "code-fork"
color = "orange"
def process_reference(self, context, name, namespace, data):
def process_reference(self, context, name, namespace, options):
import maya.cmds as cmds
from openpype.hosts.maya.api.lib import unique_namespace
@ -41,7 +41,7 @@ class AbcLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
namespace=namespace,
sharedReferenceFile=False,
groupReference=True,
groupName="{}:{}".format(namespace, name),
groupName=options['group_name'],
reference=True,
returnNewNodes=True)

View file

@ -125,14 +125,15 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
except ValueError:
family = "model"
group_name = "{}:_GRP".format(namespace)
# True by default to keep legacy behaviours
attach_to_root = options.get("attach_to_root", True)
group_name = options["group_name"]
with maintained_selection():
cmds.loadPlugin("AbcImport.mll", quiet=True)
file_url = self.prepare_root_value(self.fname,
context["project"]["name"])
nodes = cmds.file(file_url,
namespace=namespace,
sharedReferenceFile=False,

View file

@ -19,8 +19,7 @@ class YetiRigLoader(openpype.hosts.maya.api.plugin.ReferenceLoader):
def process_reference(
self, context, name=None, namespace=None, options=None
):
group_name = "{}:{}".format(namespace, name)
group_name = options['group_name']
with lib.maintained_selection():
file_url = self.prepare_root_value(
self.fname, context["project"]["name"]

View file

@ -26,7 +26,7 @@ HARDLINK = 2
@attr.s
class TextureResult:
class TextureResult(object):
"""The resulting texture of a processed file for a resource"""
# Path to the file
path = attr.ib()

View file

@ -255,7 +255,7 @@ class ValidateMeshHasOverlappingUVs(pyblish.api.InstancePlugin):
# Store original uv set
original_current_uv_set = cmds.polyUVSet(mesh,
query=True,
currentUVSet=True)
currentUVSet=True)[0]
overlapping_faces = []
for uv_set in cmds.polyUVSet(mesh, query=True, allUVSets=True):