From 4bb3da32c086bfe43e42bd3107a76c0b30d7d513 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 31 Mar 2023 15:56:19 +0200 Subject: [PATCH 01/40] get instances and set frameStart attribute --- openpype/hosts/maya/api/lib.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index cb01a847ba2..c38bb0290e1 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2299,6 +2299,24 @@ def reset_frame_range(playback=True, render=True, fps=True): cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) + instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) + + for instance in instances: + if not cmds.attributeQuery("id", node=instance, exists=True): + continue + + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue + + cmds.setAttr("{}.frameStart".format(instance), frame_start) + def reset_scene_resolution(): """Apply the scene resolution from the project definition From 7c46ed1326cc5b0062ea697452647dccaa777473 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 5 Apr 2023 15:26:04 +0200 Subject: [PATCH 02/40] update animation instance frames attribute on reset frame range --- openpype/hosts/maya/api/lib.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index c38bb0290e1..18daca063bc 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2306,6 +2306,12 @@ def reset_frame_range(playback=True, render=True, fps=True): recursive=True, objectsOnly=True ) + frames_attributes = { + 'frameStart': frame_start, + 'frameEnd': frame_end, + 'handleStart': handle_start, + 'handleEnd': handle_end + } for instance in instances: if not cmds.attributeQuery("id", node=instance, exists=True): @@ -2315,7 +2321,11 @@ def reset_frame_range(playback=True, render=True, fps=True): if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue - cmds.setAttr("{}.frameStart".format(instance), frame_start) + for key, value in frames_attributes.items(): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From 68e3d1d72092e3ff6ddcb7bd0d95d2e2531055a1 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Tue, 11 Apr 2023 16:58:37 +0200 Subject: [PATCH 03/40] check if attribute exsits before modifying it --- openpype/hosts/maya/api/lib.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 18daca063bc..95ced652eca 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2314,18 +2314,16 @@ def reset_frame_range(playback=True, render=True, fps=True): } for instance in instances: - if not cmds.attributeQuery("id", node=instance, exists=True): - continue - id_attr = "{}.id".format(instance) if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue for key, value in frames_attributes.items(): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + if cmds.attributeQuery(key, node=instance, exists=True): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From 618a45999784ba77a8cd1656775418a97603dd76 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 12 Apr 2023 13:58:40 +0200 Subject: [PATCH 04/40] add a setting in maya project settings to enable updating animation instances --- .../defaults/project_settings/maya.json | 3 ++ .../projects_schema/schema_project_maya.json | 32 +++++-------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index a2a43eefb54..2660fc7360f 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -456,6 +456,9 @@ "destination-path": [] } }, + "update_instances": { + "enabled": false + }, "scriptsmenu": { "name": "OpenPype Tools", "definition": [ diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json index b27d7958064..dca648e896a 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -188,35 +188,19 @@ }, { "type": "dict", - "key": "include_handles", "collapsible": true, - "label": "Include/Exclude Handles in default playback & render range", + "key": "update_instances", + "label": "Update animation instances on Reset Frame Range", + "checkbox_key": "enabled", "children": [ { - "key": "include_handles_default", - "label": "Include handles by default", - "type": "boolean" + "type": "label", + "label": "If enabled, the frame range and the handles of all the animation instances will be updated when using the 'Reset Frange Range' functionality" }, { - "type": "list", - "key": "per_task_type", - "label": "Include/exclude handles by task type", - "use_label_wrap": true, - "object_type": { - "type": "dict", - "children": [ - { - "type": "task-types-enum", - "key": "task_type", - "label": "Task types" - }, - { - "type": "boolean", - "key": "include_handles", - "label": "Include handles" - } - ] - } + "type": "boolean", + "key": "enabled", + "label": "Enabled" } ] }, From de0b46d42861350fac5ef30dc1f07501e0fb316e Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 12 Apr 2023 14:07:19 +0200 Subject: [PATCH 05/40] check if update instances is enabled in settings --- openpype/hosts/maya/api/lib.py | 49 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 95ced652eca..221b6774591 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2214,6 +2214,7 @@ def get_frame_range(include_animation_range=False): project_name = get_current_project_name() asset_name = get_current_asset_name() asset = get_asset_by_name(project_name, asset_name) + settings = get_project_settings(project_name) frame_start = asset["data"].get("frameStart") frame_end = asset["data"].get("frameEnd") @@ -2299,31 +2300,33 @@ def reset_frame_range(playback=True, render=True, fps=True): cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) - instances = cmds.ls( - "*.id", - long=True, - type="objectSet", - recursive=True, - objectsOnly=True - ) - frames_attributes = { - 'frameStart': frame_start, - 'frameEnd': frame_end, - 'handleStart': handle_start, - 'handleEnd': handle_end - } + # Update animation instances attributes if enabled in settings + if settings["maya"]["update_instances"]["enabled"]: + instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) + frames_attributes = { + 'frameStart': frame_start, + 'frameEnd': frame_end, + 'handleStart': handle_start, + 'handleEnd': handle_end + } - for instance in instances: - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue + for instance in instances: + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue - for key, value in frames_attributes.items(): - if cmds.attributeQuery(key, node=instance, exists=True): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + for key, value in frames_attributes.items(): + if cmds.attributeQuery(key, node=instance, exists=True): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From ce90cb726809315087c6f2dab5f44009ecf92fd9 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 13 Apr 2023 10:57:53 +0200 Subject: [PATCH 06/40] resolve conflicts --- openpype/hosts/maya/api/lib.py | 228 +++++++-------------------------- 1 file changed, 43 insertions(+), 185 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 221b6774591..a68a773c8d1 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -32,17 +32,12 @@ load_container, registered_host, ) -from openpype.pipeline.create import ( - legacy_create, - get_legacy_creator_by_name, -) 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 self = sys.modules[__name__] @@ -354,13 +349,11 @@ def collect_animation_data(fps=False): # get scene values as defaults frame_start = cmds.playbackOptions(query=True, minTime=True) frame_end = cmds.playbackOptions(query=True, maxTime=True) - frame_start_handle = cmds.playbackOptions( - query=True, animationStartTime=True - ) - frame_end_handle = cmds.playbackOptions(query=True, animationEndTime=True) + handle_start = cmds.playbackOptions(query=True, animationStartTime=True) + handle_end = cmds.playbackOptions(query=True, animationEndTime=True) - handle_start = frame_start - frame_start_handle - handle_end = frame_end_handle - frame_end + handle_start = frame_start - handle_start + handle_end = handle_end - frame_end # build attributes data = OrderedDict() @@ -2197,24 +2190,17 @@ def set_scene_resolution(width, height, pixelAspect): cmds.setAttr("%s.pixelAspect" % control_node, pixelAspect) -def get_frame_range(include_animation_range=False): - """Get the current assets frame range and handles. - - Args: - include_animation_range (bool, optional): Whether to include - `animationStart` and `animationEnd` keys to define the outer - range of the timeline. It is excluded by default. - - Returns: - dict: Asset's expected frame range values. - - """ +def get_frame_range(): + """Get the current assets frame range and handles.""" # Set frame start/end 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") @@ -2226,39 +2212,32 @@ def get_frame_range(include_animation_range=False): handle_start = asset["data"].get("handleStart") or 0 handle_end = asset["data"].get("handleEnd") or 0 - frame_range = { + 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, "handleStart": handle_start, "handleEnd": handle_end } - if include_animation_range: - # The animation range values are only included to define whether - # the Maya time slider should include the handles or not. - # Some usages of this function use the full dictionary to define - # instance attributes for which we want to exclude the animation - # keys. That is why these are excluded by default. - task_name = get_current_task_name() - settings = get_project_settings(project_name) - include_handles_settings = settings["maya"]["include_handles"] - current_task = asset.get("data").get("tasks").get(task_name) - - 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) - - frame_range["animationStart"] = animation_start - frame_range["animationEnd"] = animation_end - - return frame_range def reset_frame_range(playback=True, render=True, fps=True): @@ -2277,23 +2256,18 @@ def reset_frame_range(playback=True, render=True, fps=True): ) set_scene_fps(fps) - frame_range = get_frame_range(include_animation_range=True) - if not frame_range: - # No frame range data found for asset - return + frame_range = get_frame_range() - frame_start = frame_range["frameStart"] - frame_end = frame_range["frameEnd"] - animation_start = frame_range["animationStart"] - animation_end = frame_range["animationEnd"] + frame_start = frame_range["frameStart"] - int(frame_range["handleStart"]) + frame_end = frame_range["frameEnd"] + int(frame_range["handleEnd"]) if playback: - cmds.playbackOptions( - minTime=frame_start, - maxTime=frame_end, - animationStartTime=animation_start, - animationEndTime=animation_end - ) + cmds.playbackOptions(minTime=frame_start) + cmds.playbackOptions(maxTime=frame_end) + cmds.playbackOptions(animationStartTime=frame_start) + cmds.playbackOptions(animationEndTime=frame_end) + cmds.playbackOptions(minTime=frame_start) + cmds.playbackOptions(maxTime=frame_end) cmds.currentTime(frame_start) if render: @@ -2301,6 +2275,8 @@ def reset_frame_range(playback=True, render=True, fps=True): cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) # Update animation instances attributes if enabled in settings + project_name = get_current_project_name() + settings = get_project_settings(project_name) if settings["maya"]["update_instances"]["enabled"]: instances = cmds.ls( "*.id", @@ -2312,8 +2288,8 @@ def reset_frame_range(playback=True, render=True, fps=True): frames_attributes = { 'frameStart': frame_start, 'frameEnd': frame_end, - 'handleStart': handle_start, - 'handleEnd': handle_end + 'handleStart': frame_range["handleStart"], + 'handleEnd': frame_range["handleEnd"] } for instance in instances: @@ -3959,121 +3935,3 @@ def get_all_children(nodes): iterator.next() # noqa: B305 return list(traversed) - - -def get_capture_preset(task_name, task_type, subset, project_settings, log): - """Get capture preset for playblasting. - - Logic for transitioning from old style capture preset to new capture preset - profiles. - - Args: - task_name (str): Task name. - take_type (str): Task type. - subset (str): Subset name. - project_settings (dict): Project settings. - log (object): Logging object. - """ - capture_preset = None - filtering_criteria = { - "hosts": "maya", - "families": "review", - "task_names": task_name, - "task_types": task_type, - "subset": subset - } - - plugin_settings = project_settings["maya"]["publish"]["ExtractPlayblast"] - if plugin_settings["profiles"]: - profile = filter_profiles( - plugin_settings["profiles"], - filtering_criteria, - logger=log - ) - capture_preset = profile.get("capture_preset") - else: - log.warning("No profiles present for Extract Playblast") - - # Backward compatibility for deprecated Extract Playblast settings - # without profiles. - if capture_preset is None: - log.debug( - "Falling back to deprecated Extract Playblast capture preset " - "because no new style playblast profiles are defined." - ) - capture_preset = plugin_settings["capture_preset"] - - return capture_preset or {} - - -def create_rig_animation_instance( - nodes, context, namespace, options=None, log=None -): - """Create an animation publish instance for loaded rigs. - - See the RecreateRigAnimationInstance inventory action on how to use this - for loaded rig containers. - - Arguments: - nodes (list): Member nodes of the rig instance. - context (dict): Representation context of the rig container - namespace (str): Namespace of the rig container - options (dict, optional): Additional loader data - log (logging.Logger, optional): Logger to log to if provided - - Returns: - None - - """ - if options is None: - options = {} - - output = next((node for node in nodes if - node.endswith("out_SET")), None) - controls = next((node for node in nodes if - node.endswith("controls_SET")), None) - - assert output, "No out_SET in rig, this is a bug." - assert controls, "No controls_SET in rig, this is a bug." - - # Find the roots amongst the loaded nodes - roots = ( - cmds.ls(nodes, assemblies=True, long=True) or - get_highest_in_hierarchy(nodes) - ) - assert roots, "No root nodes in rig, this is a bug." - - asset = legacy_io.Session["AVALON_ASSET"] - dependency = str(context["representation"]["_id"]) - - custom_subset = options.get("animationSubsetName") - if custom_subset: - formatting_data = { - "asset_name": context['asset']['name'], - "asset_type": context['asset']['type'], - "subset": context['subset']['name'], - "family": ( - context['subset']['data'].get('family') or - context['subset']['data']['families'][0] - ) - } - namespace = get_custom_namespace( - custom_subset.format( - **formatting_data - ) - ) - - if log: - log.info("Creating subset: {}".format(namespace)) - - # Create the animation instance - creator_plugin = get_legacy_creator_by_name("CreateAnimation") - with maintained_selection(): - cmds.select([output, controls] + roots, noExpand=True) - legacy_create( - creator_plugin, - name=namespace, - asset=asset, - options={"useSelection": True}, - data={"dependencies": dependency} - ) From 7e7a2afdda9d1717c9eb8b443ee85e000eb45e0e Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Tue, 18 Apr 2023 09:31:27 +0200 Subject: [PATCH 07/40] change key and label to make the setting more understandable --- openpype/hosts/maya/api/lib.py | 2 +- openpype/settings/defaults/project_settings/maya.json | 2 +- .../schemas/projects_schema/schema_project_maya.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index a68a773c8d1..d1ee1f28e96 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2277,7 +2277,7 @@ def reset_frame_range(playback=True, render=True, fps=True): # Update animation instances attributes if enabled in settings project_name = get_current_project_name() settings = get_project_settings(project_name) - if settings["maya"]["update_instances"]["enabled"]: + if settings["maya"]["update_publishable_frame_range"]["enabled"]: instances = cmds.ls( "*.id", long=True, diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 2660fc7360f..8b7c56442d8 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -456,7 +456,7 @@ "destination-path": [] } }, - "update_instances": { + "update_publishable_frame_range": { "enabled": false }, "scriptsmenu": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json index dca648e896a..8137cf05584 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -189,13 +189,13 @@ { "type": "dict", "collapsible": true, - "key": "update_instances", - "label": "Update animation instances on Reset Frame Range", + "key": "update_publishable_frame_range", + "label": "Update publishable instances on Reset Frame Range", "checkbox_key": "enabled", "children": [ { "type": "label", - "label": "If enabled, the frame range and the handles of all the animation instances will be updated when using the 'Reset Frange Range' functionality" + "label": "If enabled, the frame range and the handles of all the publishable instances will be updated when using the 'Reset Frame Range' functionality" }, { "type": "boolean", From d522ba8be35ba5d587cce6245057915e43f1dfe5 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Tue, 18 Apr 2023 10:03:24 +0200 Subject: [PATCH 08/40] add 'instances' to reset_frame_range function arguments and make sure it does not update frame range instances on creating render settings --- openpype/hosts/maya/api/lib.py | 63 ++++++++++--------- openpype/hosts/maya/api/lib_rendersettings.py | 7 ++- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index d1ee1f28e96..b3216340c68 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2240,7 +2240,7 @@ def get_frame_range(): } -def reset_frame_range(playback=True, render=True, fps=True): +def reset_frame_range(playback=True, render=True, fps=True, instances=True): """Set frame range to current asset Args: @@ -2249,6 +2249,8 @@ def reset_frame_range(playback=True, render=True, fps=True): render (bool, Optional): Whether to set the maya render frame range. Defaults to True. fps (bool, Optional): Whether to set scene FPS. Defaults to True. + instances (bool, Optional): Whether to update publishable instances. + Defaults to True. """ if fps: fps = convert_to_maya_fps( @@ -2274,35 +2276,40 @@ def reset_frame_range(playback=True, render=True, fps=True): cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) - # Update animation instances attributes if enabled in settings - project_name = get_current_project_name() - settings = get_project_settings(project_name) - if settings["maya"]["update_publishable_frame_range"]["enabled"]: - instances = cmds.ls( - "*.id", - long=True, - type="objectSet", - recursive=True, - objectsOnly=True - ) - frames_attributes = { - 'frameStart': frame_start, - 'frameEnd': frame_end, - 'handleStart': frame_range["handleStart"], - 'handleEnd': frame_range["handleEnd"] - } + if instances: + # Update animation instances attributes if enabled in settings + project_name = get_current_project_name() + settings = get_project_settings(project_name) + if settings["maya"]["update_publishable_frame_range"]["enabled"]: + collected_instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) + frames_attributes = { + 'frameStart': frame_start, + 'frameEnd': frame_end, + 'handleStart': frame_range["handleStart"], + 'handleEnd': frame_range["handleEnd"] + } + + for instance in collected_instances: + family_attr = "{}.family".format(instance) + if family_attr == "render": + continue - for instance in instances: - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue - for key, value in frames_attributes.items(): - if cmds.attributeQuery(key, node=instance, exists=True): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + for key, value in frames_attributes.items(): + if cmds.attributeQuery(key, node=instance, exists=True): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index eaa728a2f68..4deffcc46bf 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -158,7 +158,12 @@ def _set_arnold_settings(self, width, height): cmds.setAttr( "defaultArnoldDriver.mergeAOVs", multi_exr) self._additional_attribs_setter(additional_options) - reset_frame_range(playback=False, fps=False, render=True) + reset_frame_range( + playback=False, + fps=False, + render=True, + instances=False + ) def _set_redshift_settings(self, width, height): """Sets settings for Redshift.""" From bd844097aec9dfc8099a4fd0fabba70c3f2917c4 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 3 May 2023 15:32:06 +0200 Subject: [PATCH 09/40] merge and refactor functions to updte asset frame range --- openpype/hosts/maya/api/lib.py | 91 +++++++++++++---------------- openpype/hosts/maya/api/pipeline.py | 2 +- 2 files changed, 40 insertions(+), 53 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index b3216340c68..0cdd61901e0 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2277,39 +2277,10 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) if instances: - # Update animation instances attributes if enabled in settings project_name = get_current_project_name() settings = get_project_settings(project_name) if settings["maya"]["update_publishable_frame_range"]["enabled"]: - collected_instances = cmds.ls( - "*.id", - long=True, - type="objectSet", - recursive=True, - objectsOnly=True - ) - frames_attributes = { - 'frameStart': frame_start, - 'frameEnd': frame_end, - 'handleStart': frame_range["handleStart"], - 'handleEnd': frame_range["handleEnd"] - } - - for instance in collected_instances: - family_attr = "{}.family".format(instance) - if family_attr == "render": - continue - - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue - - for key, value in frames_attributes.items(): - if cmds.attributeQuery(key, node=instance, exists=True): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + update_assets_frame_range() def reset_scene_resolution(): @@ -3140,32 +3111,48 @@ def remove_render_layer_observer(): pass -def update_content_on_context_change(): - """ - This will update scene content to match new asset on context change - """ - scene_sets = cmds.listSets(allSets=True) +def update_assets_frame_range(): + collected_instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) asset_doc = get_current_project_asset() new_asset = asset_doc["name"] new_data = asset_doc["data"] - for s in scene_sets: - try: - if cmds.getAttr("{}.id".format(s)) == "pyblish.avalon.instance": - attr = cmds.listAttr(s) - print(s) - if "asset" in attr: - print(" - setting asset to: [ {} ]".format(new_asset)) - cmds.setAttr("{}.asset".format(s), - new_asset, type="string") - if "frameStart" in attr: - cmds.setAttr("{}.frameStart".format(s), - new_data["frameStart"]) - if "frameEnd" in attr: - cmds.setAttr("{}.frameEnd".format(s), - new_data["frameEnd"],) - except ValueError: - pass + frames_attributes = { + 'frameStart': new_data["frameStart"], + 'frameEnd': new_data["frameEnd"], + 'handleStart': new_data["handleStart"], + 'handleEnd': new_data["handleEnd"], + 'asset': new_asset + } + + for instance in collected_instances: + family_attr = "{}.family".format(instance) + if family_attr == "render": + continue + + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue + + for key, value in frames_attributes.items(): + if cmds.attributeQuery(key, node=instance, exists=True): + if key == 'asset': + cmds.setAttr( + "{}.{}".format(instance, key), + value, + type="string" + ) + else: + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def show_message(title, msg): from qtpy import QtWidgets diff --git a/openpype/hosts/maya/api/pipeline.py b/openpype/hosts/maya/api/pipeline.py index 5323717fa72..f1ee6f485c6 100644 --- a/openpype/hosts/maya/api/pipeline.py +++ b/openpype/hosts/maya/api/pipeline.py @@ -653,7 +653,7 @@ def on_task_changed(): with lib.suspended_refresh(): lib.set_context_settings() - lib.update_content_on_context_change() + lib.update_assets_frame_range() msg = " project: {}\n asset: {}\n task:{}".format( legacy_io.active_project(), From 3c2075ddc11da2bae8834a2963d1b8949a8487e1 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 12 May 2023 11:48:43 +0200 Subject: [PATCH 10/40] add a 'type' key to the 'include handles' setting of maya --- .../projects_schema/schema_project_maya.json | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json index 8137cf05584..3ca0cfbbb86 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -204,6 +204,40 @@ } ] }, + { + "type": "dict", + "key": "include_handles", + "collapsible": true, + "label": "Include/Exclude Handles in default playback & render range", + "children": [ + { + "key": "include_handles_default", + "label": "Include handles by default", + "type": "boolean" + }, + { + "type": "list", + "key": "per_task_type", + "label": "Include/exclude handles by task type", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "task-types-enum", + "key": "task_type", + "label": "Task types" + }, + { + "type": "boolean", + "key": "include_handles", + "label": "Include handles" + } + ] + } + } + ] + }, { "type": "schema", "name": "schema_scriptsmenu" From ee81e26e01f5e12f582d311d5fb60cfefa4e552a Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 12 May 2023 15:58:05 +0200 Subject: [PATCH 11/40] change function name + docstrings --- openpype/hosts/maya/api/lib.py | 8 ++++++-- openpype/hosts/maya/api/pipeline.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 0cdd61901e0..dfc095c6dad 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2280,7 +2280,7 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): project_name = get_current_project_name() settings = get_project_settings(project_name) if settings["maya"]["update_publishable_frame_range"]["enabled"]: - update_assets_frame_range() + update_instances_frame_range() def reset_scene_resolution(): @@ -3111,7 +3111,10 @@ def remove_render_layer_observer(): pass -def update_assets_frame_range(): +def update_instances_frame_range(): + """Update 'frameStart', 'frameEnd', 'handleStart', 'handleEnd' and 'asset' + attributes of sets that got one, execpt if instance family is 'render' + """ collected_instances = cmds.ls( "*.id", long=True, @@ -3154,6 +3157,7 @@ def update_assets_frame_range(): value ) + def show_message(title, msg): from qtpy import QtWidgets from openpype.widgets import message_window diff --git a/openpype/hosts/maya/api/pipeline.py b/openpype/hosts/maya/api/pipeline.py index f1ee6f485c6..9232a0651f5 100644 --- a/openpype/hosts/maya/api/pipeline.py +++ b/openpype/hosts/maya/api/pipeline.py @@ -653,7 +653,7 @@ def on_task_changed(): with lib.suspended_refresh(): lib.set_context_settings() - lib.update_assets_frame_range() + lib.update_instances_frame_range() msg = " project: {}\n asset: {}\n task:{}".format( legacy_io.active_project(), From 19568bdc66495b47b5d871870993a4b01cafe1ee Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 12 May 2023 16:01:52 +0200 Subject: [PATCH 12/40] verify that 'family' attributes exists and equals to 'render' --- openpype/hosts/maya/api/lib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index dfc095c6dad..84d91bbb3c4 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3136,7 +3136,8 @@ def update_instances_frame_range(): for instance in collected_instances: family_attr = "{}.family".format(instance) - if family_attr == "render": + if (cmds.attributeQuery('family', node=instance, exists=True) and + cmds.getAttr(family_attr) == "render"): continue id_attr = "{}.id".format(instance) From 50f1b5fb176e0ee388650d75789870274b8be5f2 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Mon, 15 May 2023 16:55:19 +0200 Subject: [PATCH 13/40] check id attribute before family attribute --- openpype/hosts/maya/api/lib.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 84d91bbb3c4..4910ce7eeda 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3123,27 +3123,28 @@ def update_instances_frame_range(): objectsOnly=True ) asset_doc = get_current_project_asset() - new_asset = asset_doc["name"] - new_data = asset_doc["data"] + asset_name = asset_doc["name"] + asset_data = asset_doc["data"] frames_attributes = { - 'frameStart': new_data["frameStart"], - 'frameEnd': new_data["frameEnd"], - 'handleStart': new_data["handleStart"], - 'handleEnd': new_data["handleEnd"], - 'asset': new_asset + 'frameStart': asset_data["frameStart"], + 'frameEnd': asset_data["frameEnd"], + 'handleStart': asset_data["handleStart"], + 'handleEnd': asset_data["handleEnd"], + 'asset': asset_name } for instance in collected_instances: - family_attr = "{}.family".format(instance) - if (cmds.attributeQuery('family', node=instance, exists=True) and - cmds.getAttr(family_attr) == "render"): - continue - id_attr = "{}.id".format(instance) if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue + if ( + cmds.attributeQuery('family', node=instance, exists=True) and + cmds.getAttr("{}.family".format(instance)) == "render" + ): + continue + for key, value in frames_attributes.items(): if cmds.attributeQuery(key, node=instance, exists=True): if key == 'asset': From acb83a3bf19d0d0c25413f2b0e652f58bd15b2b6 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Mon, 15 May 2023 17:12:13 +0200 Subject: [PATCH 14/40] cosmetic refactoring --- openpype/hosts/maya/api/lib.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 4910ce7eeda..c84b401331b 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3123,15 +3123,14 @@ def update_instances_frame_range(): objectsOnly=True ) asset_doc = get_current_project_asset() - asset_name = asset_doc["name"] - asset_data = asset_doc["data"] + asset_data = asset_doc["data"] frames_attributes = { 'frameStart': asset_data["frameStart"], 'frameEnd': asset_data["frameEnd"], 'handleStart': asset_data["handleStart"], 'handleEnd': asset_data["handleEnd"], - 'asset': asset_name + 'asset': asset_doc['name'] } for instance in collected_instances: From 5ae9c3e3a0b02ea08ce45832c2b14387dcb4b01d Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 09:37:37 +0200 Subject: [PATCH 15/40] rename variables --- openpype/hosts/maya/api/lib.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index c84b401331b..bcc25b703ac 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -349,11 +349,11 @@ def collect_animation_data(fps=False): # get scene values as defaults 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) + frame_start_handle = cmds.playbackOptions(query=True, animationStartTime=True) + frame_end_handle = cmds.playbackOptions(query=True, animationEndTime=True) - handle_start = frame_start - handle_start - handle_end = handle_end - frame_end + handle_start = frame_start - frame_start_handle + handle_end = frame_end_handle - frame_end # build attributes data = OrderedDict() From 32d19b8afa61fa9ed195231b0eb669c4c0423d6f Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 09:53:16 +0200 Subject: [PATCH 16/40] remove playbackOptions command from get_frame_range function --- openpype/hosts/maya/api/lib.py | 36 ++++++++++++---------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index bcc25b703ac..3e73bdf307b 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2224,19 +2224,11 @@ def get_frame_range(): 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, - "handleStart": handle_start, - "handleEnd": handle_end + "animationStart": animation_start, + "animationEnd": animation_end } @@ -2259,22 +2251,20 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): set_scene_fps(fps) frame_range = get_frame_range() - - frame_start = frame_range["frameStart"] - int(frame_range["handleStart"]) - frame_end = frame_range["frameEnd"] + int(frame_range["handleEnd"]) - if playback: - cmds.playbackOptions(minTime=frame_start) - cmds.playbackOptions(maxTime=frame_end) - cmds.playbackOptions(animationStartTime=frame_start) - cmds.playbackOptions(animationEndTime=frame_end) - cmds.playbackOptions(minTime=frame_start) - cmds.playbackOptions(maxTime=frame_end) - cmds.currentTime(frame_start) + cmds.playbackOptions( + minTime=frame_range["frameStart"], + maxTime=frame_range["frameEnd"], + animationStartTime=frame_range["animationStart"], + animationEndTime=frame_range["animationEnd"] + ) + cmds.currentTime(frame_range["frameStart"]) if render: - cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) - cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) + cmds.setAttr( + "defaultRenderGlobals.startFrame", frame_range["frameStart"] + ) + cmds.setAttr("defaultRenderGlobals.endFrame", frame_range["frameEnd"]) if instances: project_name = get_current_project_name() From 7284d39b9829d87fa284f071503c34624dcabb0e Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 09:54:54 +0200 Subject: [PATCH 17/40] fix linting error --- openpype/hosts/maya/api/lib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 3e73bdf307b..e6b9b424580 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -349,7 +349,9 @@ def collect_animation_data(fps=False): # get scene values as defaults frame_start = cmds.playbackOptions(query=True, minTime=True) frame_end = cmds.playbackOptions(query=True, maxTime=True) - frame_start_handle = cmds.playbackOptions(query=True, animationStartTime=True) + frame_start_handle = cmds.playbackOptions( + query=True, animationStartTime=True + ) frame_end_handle = cmds.playbackOptions(query=True, animationEndTime=True) handle_start = frame_start - frame_start_handle From 43a41b12dd27c16cb633d3719431768b483dfea9 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 11:24:11 +0200 Subject: [PATCH 18/40] add functions that were accidently removed --- openpype/hosts/maya/api/lib.py | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index e6b9b424580..e0f50612323 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -32,12 +32,17 @@ load_container, registered_host, ) +from openpype.pipeline.create import ( + legacy_create, + get_legacy_creator_by_name +) 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 self = sys.modules[__name__] @@ -3926,3 +3931,122 @@ def get_all_children(nodes): iterator.next() # noqa: B305 return list(traversed) + + +def get_capture_preset(task_name, task_type, subset, project_settings, log): + """Get capture preset for playblasting. + + Logic for transitioning from old style capture preset to new capture preset + profiles. + + Args: + task_name (str): Task name. + take_type (str): Task type. + subset (str): Subset name. + project_settings (dict): Project settings. + log (object): Logging object. + """ + capture_preset = None + filtering_criteria = { + "hosts": "maya", + "families": "review", + "task_names": task_name, + "task_types": task_type, + "subset": subset + } + + plugin_settings = project_settings["maya"]["publish"]["ExtractPlayblast"] + if plugin_settings["profiles"]: + profile = filter_profiles( + plugin_settings["profiles"], + filtering_criteria, + logger=log + ) + capture_preset = profile.get("capture_preset") + else: + log.warning("No profiles present for Extract Playblast") + + # Backward compatibility for deprecated Extract Playblast settings + # without profiles. + if capture_preset is None: + log.debug( + "Falling back to deprecated Extract Playblast capture preset " + "because no new style playblast profiles are defined." + ) + capture_preset = plugin_settings["capture_preset"] + + return capture_preset or {} + + +def create_rig_animation_instance( + nodes, context, namespace, options=None, log=None +): + """Create an animation publish instance for loaded rigs. + + See the RecreateRigAnimationInstance inventory action on how to use this + for loaded rig containers. + + Arguments: + nodes (list): Member nodes of the rig instance. + context (dict): Representation context of the rig container + namespace (str): Namespace of the rig container + options (dict, optional): Additional loader data + log (logging.Logger, optional): Logger to log to if provided + + Returns: + None + + """ + if options is None: + options = {} + + output = next((node for node in nodes if + node.endswith("out_SET")), None) + controls = next((node for node in nodes if + node.endswith("controls_SET")), None) + + assert output, "No out_SET in rig, this is a bug." + assert controls, "No controls_SET in rig, this is a bug." + + # Find the roots amongst the loaded nodes + roots = ( + cmds.ls(nodes, assemblies=True, long=True) or + get_highest_in_hierarchy(nodes) + ) + assert roots, "No root nodes in rig, this is a bug." + + asset = legacy_io.Session["AVALON_ASSET"] + dependency = str(context["representation"]["_id"]) + + custom_subset = options.get("animationSubsetName") + if custom_subset: + formatting_data = { + "asset_name": context['asset']['name'], + "asset_type": context['asset']['type'], + "subset": context['subset']['name'], + "family": ( + context['subset']['data'].get('family') or + context['subset']['data']['families'][0] + ) + } + namespace = get_custom_namespace( + custom_subset.format( + **formatting_data + ) + ) + + if log: + log.info("Creating subset: {}".format(namespace)) + + # Create the animation instance + creator_plugin = get_legacy_creator_by_name("CreateAnimation") + with maintained_selection(): + cmds.select([output, controls] + roots, noExpand=True) + legacy_create( + creator_plugin, + name=namespace, + asset=asset, + options={"useSelection": True}, + data={"dependencies": dependency} + ) + From 95443548c3cfe0dc90ffeae3a07c629094d312c8 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 11:36:03 +0200 Subject: [PATCH 19/40] fix wrong rebase --- openpype/hosts/maya/api/lib.py | 90 ++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index e0f50612323..ca8c3b76909 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2197,17 +2197,21 @@ def set_scene_resolution(width, height, pixelAspect): cmds.setAttr("%s.pixelAspect" % control_node, pixelAspect) -def get_frame_range(): - """Get the current assets frame range and handles.""" +def get_frame_range(include_animation_range=False): + """Get the current assets frame range and handles. + + Args: + include_animation_range (bool, optional): Whether to include + `animationStart` and `animationEnd` keys to define the outer + range of the timeline. It is excluded by default. + Returns: + dict: Asset's expected frame range values. + """ # Set frame start/end 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") @@ -2219,25 +2223,41 @@ 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) - - return { + frame_range = { "frameStart": frame_start, "frameEnd": frame_end, - "animationStart": animation_start, - "animationEnd": animation_end + "handleStart": handle_start, + "handleEnd": handle_end } + if include_animation_range: + # The animation range values are only included to define whether + # the Maya time slider should include the handles or not. + # Some usages of this function use the full dictionary to define + # instance attributes for which we want to exclude the animation + # keys. That is why these are excluded by default. + task_name = get_current_task_name() + settings = get_project_settings(project_name) + include_handles_settings = settings["maya"]["include_handles"] + current_task = asset.get("data").get("tasks").get(task_name) + + 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) + + frame_range["animationStart"] = animation_start + frame_range["animationEnd"] = animation_end + + return frame_range + def reset_frame_range(playback=True, render=True, fps=True, instances=True): """Set frame range to current asset @@ -2257,21 +2277,28 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): ) set_scene_fps(fps) - frame_range = get_frame_range() + frame_range = get_frame_range(include_animation_range=True) + if not frame_range: + # No frame range data found for asset + return + + frame_start = frame_range["frameStart"] + frame_end = frame_range["frameEnd"] + animation_start = frame_range["animationStart"] + animation_end = frame_range["animationEnd"] + if playback: cmds.playbackOptions( - minTime=frame_range["frameStart"], - maxTime=frame_range["frameEnd"], - animationStartTime=frame_range["animationStart"], - animationEndTime=frame_range["animationEnd"] + minTime=frame_start, + maxTime=frame_end, + animationStartTime=animation_start, + animationEndTime=animation_end ) - cmds.currentTime(frame_range["frameStart"]) + cmds.currentTime(frame_start) if render: - cmds.setAttr( - "defaultRenderGlobals.startFrame", frame_range["frameStart"] - ) - cmds.setAttr("defaultRenderGlobals.endFrame", frame_range["frameEnd"]) + cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) + cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) if instances: project_name = get_current_project_name() @@ -4049,4 +4076,3 @@ def create_rig_animation_instance( options={"useSelection": True}, data={"dependencies": dependency} ) - From 731ab9f22b7961e014cd3ad96c6e6af78a16f71c Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 31 Mar 2023 15:56:19 +0200 Subject: [PATCH 20/40] get instances and set frameStart attribute --- openpype/hosts/maya/api/lib.py | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index ca8c3b76909..32e0ebb9c1d 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2300,11 +2300,23 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) - if instances: - project_name = get_current_project_name() - settings = get_project_settings(project_name) - if settings["maya"]["update_publishable_frame_range"]["enabled"]: - update_instances_frame_range() + instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) + + for instance in instances: + if not cmds.attributeQuery("id", node=instance, exists=True): + continue + + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue + + cmds.setAttr("{}.frameStart".format(instance), frame_start) def reset_scene_resolution(): From c03d3ab2e0b536627b01be38fea12f755a85c077 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 5 Apr 2023 15:26:04 +0200 Subject: [PATCH 21/40] update animation instance frames attribute on reset frame range --- openpype/hosts/maya/api/lib.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 32e0ebb9c1d..d73cb3804d8 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2307,6 +2307,12 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): recursive=True, objectsOnly=True ) + frames_attributes = { + 'frameStart': frame_start, + 'frameEnd': frame_end, + 'handleStart': handle_start, + 'handleEnd': handle_end + } for instance in instances: if not cmds.attributeQuery("id", node=instance, exists=True): @@ -2316,7 +2322,11 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue - cmds.setAttr("{}.frameStart".format(instance), frame_start) + for key, value in frames_attributes.items(): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From fb51b22e9f7f5bab2e07d0479baf08bf6a81b50a Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Tue, 11 Apr 2023 16:58:37 +0200 Subject: [PATCH 22/40] check if attribute exsits before modifying it --- openpype/hosts/maya/api/lib.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index d73cb3804d8..27cc9d0ce69 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2315,18 +2315,16 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): } for instance in instances: - if not cmds.attributeQuery("id", node=instance, exists=True): - continue - id_attr = "{}.id".format(instance) if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue for key, value in frames_attributes.items(): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + if cmds.attributeQuery(key, node=instance, exists=True): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From b6168c13a8bec8359ed11fb6a20d0427554985cc Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 12 Apr 2023 13:58:40 +0200 Subject: [PATCH 23/40] add a setting in maya project settings to enable updating animation instances --- .../defaults/project_settings/maya.json | 2 +- .../projects_schema/schema_project_maya.json | 40 ++----------------- 2 files changed, 4 insertions(+), 38 deletions(-) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 8b7c56442d8..2660fc7360f 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -456,7 +456,7 @@ "destination-path": [] } }, - "update_publishable_frame_range": { + "update_instances": { "enabled": false }, "scriptsmenu": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json index 3ca0cfbbb86..dca648e896a 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -189,13 +189,13 @@ { "type": "dict", "collapsible": true, - "key": "update_publishable_frame_range", - "label": "Update publishable instances on Reset Frame Range", + "key": "update_instances", + "label": "Update animation instances on Reset Frame Range", "checkbox_key": "enabled", "children": [ { "type": "label", - "label": "If enabled, the frame range and the handles of all the publishable instances will be updated when using the 'Reset Frame Range' functionality" + "label": "If enabled, the frame range and the handles of all the animation instances will be updated when using the 'Reset Frange Range' functionality" }, { "type": "boolean", @@ -204,40 +204,6 @@ } ] }, - { - "type": "dict", - "key": "include_handles", - "collapsible": true, - "label": "Include/Exclude Handles in default playback & render range", - "children": [ - { - "key": "include_handles_default", - "label": "Include handles by default", - "type": "boolean" - }, - { - "type": "list", - "key": "per_task_type", - "label": "Include/exclude handles by task type", - "use_label_wrap": true, - "object_type": { - "type": "dict", - "children": [ - { - "type": "task-types-enum", - "key": "task_type", - "label": "Task types" - }, - { - "type": "boolean", - "key": "include_handles", - "label": "Include handles" - } - ] - } - } - ] - }, { "type": "schema", "name": "schema_scriptsmenu" From 0fbe93990d012c5bcea89476110e72cfc8e94b44 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 12 Apr 2023 14:07:19 +0200 Subject: [PATCH 24/40] check if update instances is enabled in settings --- openpype/hosts/maya/api/lib.py | 49 ++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 27cc9d0ce69..42c6019e7b1 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2212,6 +2212,7 @@ def get_frame_range(include_animation_range=False): project_name = get_current_project_name() asset_name = get_current_asset_name() asset = get_asset_by_name(project_name, asset_name) + settings = get_project_settings(project_name) frame_start = asset["data"].get("frameStart") frame_end = asset["data"].get("frameEnd") @@ -2300,31 +2301,33 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) - instances = cmds.ls( - "*.id", - long=True, - type="objectSet", - recursive=True, - objectsOnly=True - ) - frames_attributes = { - 'frameStart': frame_start, - 'frameEnd': frame_end, - 'handleStart': handle_start, - 'handleEnd': handle_end - } + # Update animation instances attributes if enabled in settings + if settings["maya"]["update_instances"]["enabled"]: + instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) + frames_attributes = { + 'frameStart': frame_start, + 'frameEnd': frame_end, + 'handleStart': handle_start, + 'handleEnd': handle_end + } - for instance in instances: - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue + for instance in instances: + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue - for key, value in frames_attributes.items(): - if cmds.attributeQuery(key, node=instance, exists=True): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + for key, value in frames_attributes.items(): + if cmds.attributeQuery(key, node=instance, exists=True): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From a10dba4e1c8840b9d356bafd27a0d17ec8ba001d Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 13 Apr 2023 10:57:53 +0200 Subject: [PATCH 25/40] resolve conflicts --- openpype/hosts/maya/api/lib.py | 226 +++++++-------------------------- 1 file changed, 46 insertions(+), 180 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 42c6019e7b1..23faba31242 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -32,17 +32,19 @@ load_container, registered_host, ) +<<<<<<< HEAD from openpype.pipeline.create import ( legacy_create, get_legacy_creator_by_name ) +======= +>>>>>>> ec2af75dd1 (resolve conflicts) 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 self = sys.modules[__name__] @@ -354,13 +356,11 @@ def collect_animation_data(fps=False): # get scene values as defaults frame_start = cmds.playbackOptions(query=True, minTime=True) frame_end = cmds.playbackOptions(query=True, maxTime=True) - frame_start_handle = cmds.playbackOptions( - query=True, animationStartTime=True - ) - frame_end_handle = cmds.playbackOptions(query=True, animationEndTime=True) + handle_start = cmds.playbackOptions(query=True, animationStartTime=True) + handle_end = cmds.playbackOptions(query=True, animationEndTime=True) - handle_start = frame_start - frame_start_handle - handle_end = frame_end_handle - frame_end + handle_start = frame_start - handle_start + handle_end = handle_end - frame_end # build attributes data = OrderedDict() @@ -2197,22 +2197,17 @@ def set_scene_resolution(width, height, pixelAspect): cmds.setAttr("%s.pixelAspect" % control_node, pixelAspect) -def get_frame_range(include_animation_range=False): - """Get the current assets frame range and handles. - - Args: - include_animation_range (bool, optional): Whether to include - `animationStart` and `animationEnd` keys to define the outer - range of the timeline. It is excluded by default. - Returns: - dict: Asset's expected frame range values. - """ +def get_frame_range(): + """Get the current assets frame range and handles.""" # Set frame start/end 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") @@ -2224,41 +2219,33 @@ def get_frame_range(include_animation_range=False): handle_start = asset["data"].get("handleStart") or 0 handle_end = asset["data"].get("handleEnd") or 0 - frame_range = { + 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, "handleStart": handle_start, "handleEnd": handle_end } - if include_animation_range: - # The animation range values are only included to define whether - # the Maya time slider should include the handles or not. - # Some usages of this function use the full dictionary to define - # instance attributes for which we want to exclude the animation - # keys. That is why these are excluded by default. - task_name = get_current_task_name() - settings = get_project_settings(project_name) - include_handles_settings = settings["maya"]["include_handles"] - current_task = asset.get("data").get("tasks").get(task_name) - - 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) - - frame_range["animationStart"] = animation_start - frame_range["animationEnd"] = animation_end - - return frame_range - def reset_frame_range(playback=True, render=True, fps=True, instances=True): """Set frame range to current asset @@ -2278,23 +2265,18 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): ) set_scene_fps(fps) - frame_range = get_frame_range(include_animation_range=True) - if not frame_range: - # No frame range data found for asset - return + frame_range = get_frame_range() - frame_start = frame_range["frameStart"] - frame_end = frame_range["frameEnd"] - animation_start = frame_range["animationStart"] - animation_end = frame_range["animationEnd"] + frame_start = frame_range["frameStart"] - int(frame_range["handleStart"]) + frame_end = frame_range["frameEnd"] + int(frame_range["handleEnd"]) if playback: - cmds.playbackOptions( - minTime=frame_start, - maxTime=frame_end, - animationStartTime=animation_start, - animationEndTime=animation_end - ) + cmds.playbackOptions(minTime=frame_start) + cmds.playbackOptions(maxTime=frame_end) + cmds.playbackOptions(animationStartTime=frame_start) + cmds.playbackOptions(animationEndTime=frame_end) + cmds.playbackOptions(minTime=frame_start) + cmds.playbackOptions(maxTime=frame_end) cmds.currentTime(frame_start) if render: @@ -2302,6 +2284,8 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) # Update animation instances attributes if enabled in settings + project_name = get_current_project_name() + settings = get_project_settings(project_name) if settings["maya"]["update_instances"]["enabled"]: instances = cmds.ls( "*.id", @@ -2313,8 +2297,8 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): frames_attributes = { 'frameStart': frame_start, 'frameEnd': frame_end, - 'handleStart': handle_start, - 'handleEnd': handle_end + 'handleStart': frame_range["handleStart"], + 'handleEnd': frame_range["handleEnd"] } for instance in instances: @@ -3981,121 +3965,3 @@ def get_all_children(nodes): iterator.next() # noqa: B305 return list(traversed) - - -def get_capture_preset(task_name, task_type, subset, project_settings, log): - """Get capture preset for playblasting. - - Logic for transitioning from old style capture preset to new capture preset - profiles. - - Args: - task_name (str): Task name. - take_type (str): Task type. - subset (str): Subset name. - project_settings (dict): Project settings. - log (object): Logging object. - """ - capture_preset = None - filtering_criteria = { - "hosts": "maya", - "families": "review", - "task_names": task_name, - "task_types": task_type, - "subset": subset - } - - plugin_settings = project_settings["maya"]["publish"]["ExtractPlayblast"] - if plugin_settings["profiles"]: - profile = filter_profiles( - plugin_settings["profiles"], - filtering_criteria, - logger=log - ) - capture_preset = profile.get("capture_preset") - else: - log.warning("No profiles present for Extract Playblast") - - # Backward compatibility for deprecated Extract Playblast settings - # without profiles. - if capture_preset is None: - log.debug( - "Falling back to deprecated Extract Playblast capture preset " - "because no new style playblast profiles are defined." - ) - capture_preset = plugin_settings["capture_preset"] - - return capture_preset or {} - - -def create_rig_animation_instance( - nodes, context, namespace, options=None, log=None -): - """Create an animation publish instance for loaded rigs. - - See the RecreateRigAnimationInstance inventory action on how to use this - for loaded rig containers. - - Arguments: - nodes (list): Member nodes of the rig instance. - context (dict): Representation context of the rig container - namespace (str): Namespace of the rig container - options (dict, optional): Additional loader data - log (logging.Logger, optional): Logger to log to if provided - - Returns: - None - - """ - if options is None: - options = {} - - output = next((node for node in nodes if - node.endswith("out_SET")), None) - controls = next((node for node in nodes if - node.endswith("controls_SET")), None) - - assert output, "No out_SET in rig, this is a bug." - assert controls, "No controls_SET in rig, this is a bug." - - # Find the roots amongst the loaded nodes - roots = ( - cmds.ls(nodes, assemblies=True, long=True) or - get_highest_in_hierarchy(nodes) - ) - assert roots, "No root nodes in rig, this is a bug." - - asset = legacy_io.Session["AVALON_ASSET"] - dependency = str(context["representation"]["_id"]) - - custom_subset = options.get("animationSubsetName") - if custom_subset: - formatting_data = { - "asset_name": context['asset']['name'], - "asset_type": context['asset']['type'], - "subset": context['subset']['name'], - "family": ( - context['subset']['data'].get('family') or - context['subset']['data']['families'][0] - ) - } - namespace = get_custom_namespace( - custom_subset.format( - **formatting_data - ) - ) - - if log: - log.info("Creating subset: {}".format(namespace)) - - # Create the animation instance - creator_plugin = get_legacy_creator_by_name("CreateAnimation") - with maintained_selection(): - cmds.select([output, controls] + roots, noExpand=True) - legacy_create( - creator_plugin, - name=namespace, - asset=asset, - options={"useSelection": True}, - data={"dependencies": dependency} - ) From 15c672c52c6a9f0596fd5e0eececda45c1d6b650 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Tue, 18 Apr 2023 09:31:27 +0200 Subject: [PATCH 26/40] change key and label to make the setting more understandable --- openpype/hosts/maya/api/lib.py | 2 +- openpype/settings/defaults/project_settings/maya.json | 2 +- .../schemas/projects_schema/schema_project_maya.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 23faba31242..f2576f89dbe 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2286,7 +2286,7 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): # Update animation instances attributes if enabled in settings project_name = get_current_project_name() settings = get_project_settings(project_name) - if settings["maya"]["update_instances"]["enabled"]: + if settings["maya"]["update_publishable_frame_range"]["enabled"]: instances = cmds.ls( "*.id", long=True, diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 2660fc7360f..8b7c56442d8 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -456,7 +456,7 @@ "destination-path": [] } }, - "update_instances": { + "update_publishable_frame_range": { "enabled": false }, "scriptsmenu": { diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json index dca648e896a..8137cf05584 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -189,13 +189,13 @@ { "type": "dict", "collapsible": true, - "key": "update_instances", - "label": "Update animation instances on Reset Frame Range", + "key": "update_publishable_frame_range", + "label": "Update publishable instances on Reset Frame Range", "checkbox_key": "enabled", "children": [ { "type": "label", - "label": "If enabled, the frame range and the handles of all the animation instances will be updated when using the 'Reset Frange Range' functionality" + "label": "If enabled, the frame range and the handles of all the publishable instances will be updated when using the 'Reset Frame Range' functionality" }, { "type": "boolean", From d1ea654a782bef9c96896aaadbe40870fa8a9cee Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Tue, 18 Apr 2023 10:03:24 +0200 Subject: [PATCH 27/40] add 'instances' to reset_frame_range function arguments and make sure it does not update frame range instances on creating render settings --- openpype/hosts/maya/api/lib.py | 59 ++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index f2576f89dbe..f6df4226041 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2283,35 +2283,40 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) - # Update animation instances attributes if enabled in settings - project_name = get_current_project_name() - settings = get_project_settings(project_name) - if settings["maya"]["update_publishable_frame_range"]["enabled"]: - instances = cmds.ls( - "*.id", - long=True, - type="objectSet", - recursive=True, - objectsOnly=True - ) - frames_attributes = { - 'frameStart': frame_start, - 'frameEnd': frame_end, - 'handleStart': frame_range["handleStart"], - 'handleEnd': frame_range["handleEnd"] - } + if instances: + # Update animation instances attributes if enabled in settings + project_name = get_current_project_name() + settings = get_project_settings(project_name) + if settings["maya"]["update_publishable_frame_range"]["enabled"]: + collected_instances = cmds.ls( + "*.id", + long=True, + type="objectSet", + recursive=True, + objectsOnly=True + ) + frames_attributes = { + 'frameStart': frame_start, + 'frameEnd': frame_end, + 'handleStart': frame_range["handleStart"], + 'handleEnd': frame_range["handleEnd"] + } + + for instance in collected_instances: + family_attr = "{}.family".format(instance) + if family_attr == "render": + continue - for instance in instances: - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + continue - for key, value in frames_attributes.items(): - if cmds.attributeQuery(key, node=instance, exists=True): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + for key, value in frames_attributes.items(): + if cmds.attributeQuery(key, node=instance, exists=True): + cmds.setAttr( + "{}.{}".format(instance, key), + value + ) def reset_scene_resolution(): From ebd3aba515b605ba13837065420ff025e9911a17 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Wed, 3 May 2023 15:32:06 +0200 Subject: [PATCH 28/40] merge and refactor functions to updte asset frame range --- openpype/hosts/maya/api/lib.py | 60 +++++++---------------------- openpype/hosts/maya/api/pipeline.py | 2 +- 2 files changed, 14 insertions(+), 48 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index f6df4226041..dea94b38d28 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2284,39 +2284,10 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) if instances: - # Update animation instances attributes if enabled in settings project_name = get_current_project_name() settings = get_project_settings(project_name) if settings["maya"]["update_publishable_frame_range"]["enabled"]: - collected_instances = cmds.ls( - "*.id", - long=True, - type="objectSet", - recursive=True, - objectsOnly=True - ) - frames_attributes = { - 'frameStart': frame_start, - 'frameEnd': frame_end, - 'handleStart': frame_range["handleStart"], - 'handleEnd': frame_range["handleEnd"] - } - - for instance in collected_instances: - family_attr = "{}.family".format(instance) - if family_attr == "render": - continue - - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue - - for key, value in frames_attributes.items(): - if cmds.attributeQuery(key, node=instance, exists=True): - cmds.setAttr( - "{}.{}".format(instance, key), - value - ) + update_assets_frame_range() def reset_scene_resolution(): @@ -3147,10 +3118,7 @@ def remove_render_layer_observer(): pass -def update_instances_frame_range(): - """Update 'frameStart', 'frameEnd', 'handleStart', 'handleEnd' and 'asset' - attributes of sets that got one, execpt if instance family is 'render' - """ +def update_assets_frame_range(): collected_instances = cmds.ls( "*.id", long=True, @@ -3159,25 +3127,24 @@ def update_instances_frame_range(): objectsOnly=True ) asset_doc = get_current_project_asset() + new_asset = asset_doc["name"] + new_data = asset_doc["data"] - asset_data = asset_doc["data"] frames_attributes = { - 'frameStart': asset_data["frameStart"], - 'frameEnd': asset_data["frameEnd"], - 'handleStart': asset_data["handleStart"], - 'handleEnd': asset_data["handleEnd"], - 'asset': asset_doc['name'] + 'frameStart': new_data["frameStart"], + 'frameEnd': new_data["frameEnd"], + 'handleStart': new_data["handleStart"], + 'handleEnd': new_data["handleEnd"], + 'asset': new_asset } for instance in collected_instances: - id_attr = "{}.id".format(instance) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": + family_attr = "{}.family".format(instance) + if family_attr == "render": continue - if ( - cmds.attributeQuery('family', node=instance, exists=True) and - cmds.getAttr("{}.family".format(instance)) == "render" - ): + id_attr = "{}.id".format(instance) + if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue for key, value in frames_attributes.items(): @@ -3194,7 +3161,6 @@ def update_instances_frame_range(): value ) - def show_message(title, msg): from qtpy import QtWidgets from openpype.widgets import message_window diff --git a/openpype/hosts/maya/api/pipeline.py b/openpype/hosts/maya/api/pipeline.py index 9232a0651f5..f1ee6f485c6 100644 --- a/openpype/hosts/maya/api/pipeline.py +++ b/openpype/hosts/maya/api/pipeline.py @@ -653,7 +653,7 @@ def on_task_changed(): with lib.suspended_refresh(): lib.set_context_settings() - lib.update_instances_frame_range() + lib.update_assets_frame_range() msg = " project: {}\n asset: {}\n task:{}".format( legacy_io.active_project(), From 73a0c61ef5530ecf1610f498a3164dddd06420bf Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 12 May 2023 11:48:43 +0200 Subject: [PATCH 29/40] add a 'type' key to the 'include handles' setting of maya --- .../projects_schema/schema_project_maya.json | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json index 8137cf05584..3ca0cfbbb86 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_maya.json @@ -204,6 +204,40 @@ } ] }, + { + "type": "dict", + "key": "include_handles", + "collapsible": true, + "label": "Include/Exclude Handles in default playback & render range", + "children": [ + { + "key": "include_handles_default", + "label": "Include handles by default", + "type": "boolean" + }, + { + "type": "list", + "key": "per_task_type", + "label": "Include/exclude handles by task type", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "task-types-enum", + "key": "task_type", + "label": "Task types" + }, + { + "type": "boolean", + "key": "include_handles", + "label": "Include handles" + } + ] + } + } + ] + }, { "type": "schema", "name": "schema_scriptsmenu" From 34c2dc581c5c08b0155af386edcb78d9b4151d37 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 12 May 2023 15:58:05 +0200 Subject: [PATCH 30/40] change function name + docstrings --- openpype/hosts/maya/api/lib.py | 8 ++++++-- openpype/hosts/maya/api/pipeline.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index dea94b38d28..d88e3df612e 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2287,7 +2287,7 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): project_name = get_current_project_name() settings = get_project_settings(project_name) if settings["maya"]["update_publishable_frame_range"]["enabled"]: - update_assets_frame_range() + update_instances_frame_range() def reset_scene_resolution(): @@ -3118,7 +3118,10 @@ def remove_render_layer_observer(): pass -def update_assets_frame_range(): +def update_instances_frame_range(): + """Update 'frameStart', 'frameEnd', 'handleStart', 'handleEnd' and 'asset' + attributes of sets that got one, execpt if instance family is 'render' + """ collected_instances = cmds.ls( "*.id", long=True, @@ -3161,6 +3164,7 @@ def update_assets_frame_range(): value ) + def show_message(title, msg): from qtpy import QtWidgets from openpype.widgets import message_window diff --git a/openpype/hosts/maya/api/pipeline.py b/openpype/hosts/maya/api/pipeline.py index f1ee6f485c6..9232a0651f5 100644 --- a/openpype/hosts/maya/api/pipeline.py +++ b/openpype/hosts/maya/api/pipeline.py @@ -653,7 +653,7 @@ def on_task_changed(): with lib.suspended_refresh(): lib.set_context_settings() - lib.update_assets_frame_range() + lib.update_instances_frame_range() msg = " project: {}\n asset: {}\n task:{}".format( legacy_io.active_project(), From 1d805516b983833532ba1db8b009217ee35a4825 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Fri, 12 May 2023 16:01:52 +0200 Subject: [PATCH 31/40] verify that 'family' attributes exists and equals to 'render' --- openpype/hosts/maya/api/lib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index d88e3df612e..ce117b88627 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3143,7 +3143,8 @@ def update_instances_frame_range(): for instance in collected_instances: family_attr = "{}.family".format(instance) - if family_attr == "render": + if (cmds.attributeQuery('family', node=instance, exists=True) and + cmds.getAttr(family_attr) == "render"): continue id_attr = "{}.id".format(instance) From 8f3dc4c14967d12e0d3f9d391168b2c566378aaf Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Mon, 15 May 2023 16:55:19 +0200 Subject: [PATCH 32/40] check id attribute before family attribute --- openpype/hosts/maya/api/lib.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index ce117b88627..7aae42f505f 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3130,27 +3130,28 @@ def update_instances_frame_range(): objectsOnly=True ) asset_doc = get_current_project_asset() - new_asset = asset_doc["name"] - new_data = asset_doc["data"] + asset_name = asset_doc["name"] + asset_data = asset_doc["data"] frames_attributes = { - 'frameStart': new_data["frameStart"], - 'frameEnd': new_data["frameEnd"], - 'handleStart': new_data["handleStart"], - 'handleEnd': new_data["handleEnd"], - 'asset': new_asset + 'frameStart': asset_data["frameStart"], + 'frameEnd': asset_data["frameEnd"], + 'handleStart': asset_data["handleStart"], + 'handleEnd': asset_data["handleEnd"], + 'asset': asset_name } for instance in collected_instances: - family_attr = "{}.family".format(instance) - if (cmds.attributeQuery('family', node=instance, exists=True) and - cmds.getAttr(family_attr) == "render"): - continue - id_attr = "{}.id".format(instance) if cmds.getAttr(id_attr) != "pyblish.avalon.instance": continue + if ( + cmds.attributeQuery('family', node=instance, exists=True) and + cmds.getAttr("{}.family".format(instance)) == "render" + ): + continue + for key, value in frames_attributes.items(): if cmds.attributeQuery(key, node=instance, exists=True): if key == 'asset': From 5200490ed7ab3e01441354c97a8495f1f586ce66 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Mon, 15 May 2023 17:12:13 +0200 Subject: [PATCH 33/40] cosmetic refactoring --- openpype/hosts/maya/api/lib.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 7aae42f505f..533e7767432 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3130,15 +3130,14 @@ def update_instances_frame_range(): objectsOnly=True ) asset_doc = get_current_project_asset() - asset_name = asset_doc["name"] - asset_data = asset_doc["data"] + asset_data = asset_doc["data"] frames_attributes = { 'frameStart': asset_data["frameStart"], 'frameEnd': asset_data["frameEnd"], 'handleStart': asset_data["handleStart"], 'handleEnd': asset_data["handleEnd"], - 'asset': asset_name + 'asset': asset_doc['name'] } for instance in collected_instances: From 0aa63ac40dca495aae31470f2a1ab019390b8bf2 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 09:37:37 +0200 Subject: [PATCH 34/40] rename variables --- openpype/hosts/maya/api/lib.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 533e7767432..7cb3e994175 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -356,11 +356,11 @@ def collect_animation_data(fps=False): # get scene values as defaults 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) + frame_start_handle = cmds.playbackOptions(query=True, animationStartTime=True) + frame_end_handle = cmds.playbackOptions(query=True, animationEndTime=True) - handle_start = frame_start - handle_start - handle_end = handle_end - frame_end + handle_start = frame_start - frame_start_handle + handle_end = frame_end_handle - frame_end # build attributes data = OrderedDict() From 7dcb1c89c223efafab900c1bcdf64f65170dea41 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 09:53:16 +0200 Subject: [PATCH 35/40] remove playbackOptions command from get_frame_range function --- openpype/hosts/maya/api/lib.py | 36 ++++++++++++---------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 7cb3e994175..2d351859dbd 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2231,19 +2231,11 @@ def get_frame_range(): 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, - "handleStart": handle_start, - "handleEnd": handle_end + "animationStart": animation_start, + "animationEnd": animation_end } @@ -2266,22 +2258,20 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): set_scene_fps(fps) frame_range = get_frame_range() - - frame_start = frame_range["frameStart"] - int(frame_range["handleStart"]) - frame_end = frame_range["frameEnd"] + int(frame_range["handleEnd"]) - if playback: - cmds.playbackOptions(minTime=frame_start) - cmds.playbackOptions(maxTime=frame_end) - cmds.playbackOptions(animationStartTime=frame_start) - cmds.playbackOptions(animationEndTime=frame_end) - cmds.playbackOptions(minTime=frame_start) - cmds.playbackOptions(maxTime=frame_end) - cmds.currentTime(frame_start) + cmds.playbackOptions( + minTime=frame_range["frameStart"], + maxTime=frame_range["frameEnd"], + animationStartTime=frame_range["animationStart"], + animationEndTime=frame_range["animationEnd"] + ) + cmds.currentTime(frame_range["frameStart"]) if render: - cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) - cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) + cmds.setAttr( + "defaultRenderGlobals.startFrame", frame_range["frameStart"] + ) + cmds.setAttr("defaultRenderGlobals.endFrame", frame_range["frameEnd"]) if instances: project_name = get_current_project_name() From 23ae58ec036c8438896f973471c71c8a713c21ad Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 09:54:54 +0200 Subject: [PATCH 36/40] fix linting error --- openpype/hosts/maya/api/lib.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 2d351859dbd..04832455cae 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -356,7 +356,9 @@ def collect_animation_data(fps=False): # get scene values as defaults frame_start = cmds.playbackOptions(query=True, minTime=True) frame_end = cmds.playbackOptions(query=True, maxTime=True) - frame_start_handle = cmds.playbackOptions(query=True, animationStartTime=True) + frame_start_handle = cmds.playbackOptions( + query=True, animationStartTime=True + ) frame_end_handle = cmds.playbackOptions(query=True, animationEndTime=True) handle_start = frame_start - frame_start_handle From 7a40def59295a6ea8331cee26cd932b39d4a3327 Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 11:24:11 +0200 Subject: [PATCH 37/40] add functions that were accidently removed --- openpype/hosts/maya/api/lib.py | 123 ++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 04832455cae..e0f50612323 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -32,19 +32,17 @@ load_container, registered_host, ) -<<<<<<< HEAD from openpype.pipeline.create import ( legacy_create, get_legacy_creator_by_name ) -======= ->>>>>>> ec2af75dd1 (resolve conflicts) 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 self = sys.modules[__name__] @@ -3933,3 +3931,122 @@ def get_all_children(nodes): iterator.next() # noqa: B305 return list(traversed) + + +def get_capture_preset(task_name, task_type, subset, project_settings, log): + """Get capture preset for playblasting. + + Logic for transitioning from old style capture preset to new capture preset + profiles. + + Args: + task_name (str): Task name. + take_type (str): Task type. + subset (str): Subset name. + project_settings (dict): Project settings. + log (object): Logging object. + """ + capture_preset = None + filtering_criteria = { + "hosts": "maya", + "families": "review", + "task_names": task_name, + "task_types": task_type, + "subset": subset + } + + plugin_settings = project_settings["maya"]["publish"]["ExtractPlayblast"] + if plugin_settings["profiles"]: + profile = filter_profiles( + plugin_settings["profiles"], + filtering_criteria, + logger=log + ) + capture_preset = profile.get("capture_preset") + else: + log.warning("No profiles present for Extract Playblast") + + # Backward compatibility for deprecated Extract Playblast settings + # without profiles. + if capture_preset is None: + log.debug( + "Falling back to deprecated Extract Playblast capture preset " + "because no new style playblast profiles are defined." + ) + capture_preset = plugin_settings["capture_preset"] + + return capture_preset or {} + + +def create_rig_animation_instance( + nodes, context, namespace, options=None, log=None +): + """Create an animation publish instance for loaded rigs. + + See the RecreateRigAnimationInstance inventory action on how to use this + for loaded rig containers. + + Arguments: + nodes (list): Member nodes of the rig instance. + context (dict): Representation context of the rig container + namespace (str): Namespace of the rig container + options (dict, optional): Additional loader data + log (logging.Logger, optional): Logger to log to if provided + + Returns: + None + + """ + if options is None: + options = {} + + output = next((node for node in nodes if + node.endswith("out_SET")), None) + controls = next((node for node in nodes if + node.endswith("controls_SET")), None) + + assert output, "No out_SET in rig, this is a bug." + assert controls, "No controls_SET in rig, this is a bug." + + # Find the roots amongst the loaded nodes + roots = ( + cmds.ls(nodes, assemblies=True, long=True) or + get_highest_in_hierarchy(nodes) + ) + assert roots, "No root nodes in rig, this is a bug." + + asset = legacy_io.Session["AVALON_ASSET"] + dependency = str(context["representation"]["_id"]) + + custom_subset = options.get("animationSubsetName") + if custom_subset: + formatting_data = { + "asset_name": context['asset']['name'], + "asset_type": context['asset']['type'], + "subset": context['subset']['name'], + "family": ( + context['subset']['data'].get('family') or + context['subset']['data']['families'][0] + ) + } + namespace = get_custom_namespace( + custom_subset.format( + **formatting_data + ) + ) + + if log: + log.info("Creating subset: {}".format(namespace)) + + # Create the animation instance + creator_plugin = get_legacy_creator_by_name("CreateAnimation") + with maintained_selection(): + cmds.select([output, controls] + roots, noExpand=True) + legacy_create( + creator_plugin, + name=namespace, + asset=asset, + options={"useSelection": True}, + data={"dependencies": dependency} + ) + From 5834a0f75606877d30963ed7926f86382a62193b Mon Sep 17 00:00:00 2001 From: Thomas Fricard Date: Thu, 25 May 2023 11:36:03 +0200 Subject: [PATCH 38/40] fix wrong rebase --- openpype/hosts/maya/api/lib.py | 90 ++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index e0f50612323..ca8c3b76909 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2197,17 +2197,21 @@ def set_scene_resolution(width, height, pixelAspect): cmds.setAttr("%s.pixelAspect" % control_node, pixelAspect) -def get_frame_range(): - """Get the current assets frame range and handles.""" +def get_frame_range(include_animation_range=False): + """Get the current assets frame range and handles. + + Args: + include_animation_range (bool, optional): Whether to include + `animationStart` and `animationEnd` keys to define the outer + range of the timeline. It is excluded by default. + Returns: + dict: Asset's expected frame range values. + """ # Set frame start/end 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") @@ -2219,25 +2223,41 @@ 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) - - return { + frame_range = { "frameStart": frame_start, "frameEnd": frame_end, - "animationStart": animation_start, - "animationEnd": animation_end + "handleStart": handle_start, + "handleEnd": handle_end } + if include_animation_range: + # The animation range values are only included to define whether + # the Maya time slider should include the handles or not. + # Some usages of this function use the full dictionary to define + # instance attributes for which we want to exclude the animation + # keys. That is why these are excluded by default. + task_name = get_current_task_name() + settings = get_project_settings(project_name) + include_handles_settings = settings["maya"]["include_handles"] + current_task = asset.get("data").get("tasks").get(task_name) + + 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) + + frame_range["animationStart"] = animation_start + frame_range["animationEnd"] = animation_end + + return frame_range + def reset_frame_range(playback=True, render=True, fps=True, instances=True): """Set frame range to current asset @@ -2257,21 +2277,28 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): ) set_scene_fps(fps) - frame_range = get_frame_range() + frame_range = get_frame_range(include_animation_range=True) + if not frame_range: + # No frame range data found for asset + return + + frame_start = frame_range["frameStart"] + frame_end = frame_range["frameEnd"] + animation_start = frame_range["animationStart"] + animation_end = frame_range["animationEnd"] + if playback: cmds.playbackOptions( - minTime=frame_range["frameStart"], - maxTime=frame_range["frameEnd"], - animationStartTime=frame_range["animationStart"], - animationEndTime=frame_range["animationEnd"] + minTime=frame_start, + maxTime=frame_end, + animationStartTime=animation_start, + animationEndTime=animation_end ) - cmds.currentTime(frame_range["frameStart"]) + cmds.currentTime(frame_start) if render: - cmds.setAttr( - "defaultRenderGlobals.startFrame", frame_range["frameStart"] - ) - cmds.setAttr("defaultRenderGlobals.endFrame", frame_range["frameEnd"]) + cmds.setAttr("defaultRenderGlobals.startFrame", frame_start) + cmds.setAttr("defaultRenderGlobals.endFrame", frame_end) if instances: project_name = get_current_project_name() @@ -4049,4 +4076,3 @@ def create_rig_animation_instance( options={"useSelection": True}, data={"dependencies": dependency} ) - From a83ee514876acb85d6540a75556d2d74140ea77f Mon Sep 17 00:00:00 2001 From: Thomas Fricard <51854004+friquette@users.noreply.github.com> Date: Mon, 26 Jun 2023 10:12:14 +0200 Subject: [PATCH 39/40] update docstring for reset_frame_range Co-authored-by: Roy Nieterau --- openpype/hosts/maya/api/lib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index ca8c3b76909..7da576dcb45 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2269,7 +2269,8 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): Defaults to True. fps (bool, Optional): Whether to set scene FPS. Defaults to True. instances (bool, Optional): Whether to update publishable instances. - Defaults to True. + Defaults to True. Even when True this will only reset instances if + `update_publishable_frame_range` is also enabled in project settings. """ if fps: fps = convert_to_maya_fps( From 3e4cdb40c6fefe8a51f84aa80faaec8b76ee8cf0 Mon Sep 17 00:00:00 2001 From: Thomas Fricard <51854004+friquette@users.noreply.github.com> Date: Mon, 26 Jun 2023 10:18:35 +0200 Subject: [PATCH 40/40] fix linting error --- openpype/hosts/maya/api/lib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 7da576dcb45..3f45fdb952c 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2270,7 +2270,8 @@ def reset_frame_range(playback=True, render=True, fps=True, instances=True): fps (bool, Optional): Whether to set scene FPS. Defaults to True. instances (bool, Optional): Whether to update publishable instances. Defaults to True. Even when True this will only reset instances if - `update_publishable_frame_range` is also enabled in project settings. + `update_publishable_frame_range` is also enabled + in project settings. """ if fps: fps = convert_to_maya_fps(