Skip to content
This repository has been archived by the owner on Sep 20, 2024. It is now read-only.

Commit

Permalink
Maya Instance Frame Range: Add functionality to properly update the f…
Browse files Browse the repository at this point in the history
…rame range
  • Loading branch information
BenSouchet committed Sep 11, 2024
1 parent d9731d0 commit 3960364
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 27 deletions.
88 changes: 64 additions & 24 deletions openpype/hosts/maya/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -2361,7 +2361,7 @@ def get_frame_range(include_animation_range=False):
return 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:
Expand All @@ -2370,6 +2370,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:
set_scene_fps(get_fps_for_current_context())
Expand Down Expand Up @@ -2397,6 +2399,12 @@ def reset_frame_range(playback=True, render=True, fps=True):
cmds.setAttr("defaultRenderGlobals.startFrame", animation_start)
cmds.setAttr("defaultRenderGlobals.endFrame", animation_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()


def reset_scene_resolution():
"""Apply the scene resolution from the project definition
Expand Down Expand Up @@ -2939,31 +2947,63 @@ def fix_incompatible_containers():
"ReferenceLoader", type="string")


def update_content_on_context_change():
def iter_publish_instances():
"""Iterate over publishable instances (their objectSets).
"""
This will update scene content to match new asset on context change
for node in cmds.ls(
"*.id",
long=True,
type="objectSet",
recursive=True,
objectsOnly=True
):
if cmds.getAttr("{}.id".format(node)) != "pyblish.avalon.instance":
continue
yield node


def update_instances_asset_name():
"""Update 'asset' attribute of publishable instances (their objectSets)
that got one.
"""
scene_sets = cmds.listSets(allSets=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

for instance in iter_publish_instances():
if not cmds.attributeQuery("asset", node=instance, exists=True):
continue
attr = "{}.asset".format(instance)
cmds.setAttr(attr, get_current_asset_name(), type="string")


def update_instances_frame_range():
"""Update 'frameStart', 'frameEnd', 'handleStart', 'handleEnd' and 'fps'
attributes of publishable instances (their objectSets) that got one.
"""

attributes = ["frameStart", "frameEnd", "handleStart", "handleEnd", "fps"]

attrs_per_instance = {}
for instance in iter_publish_instances():
instance_attrs = [
attr for attr in attributes
if cmds.attributeQuery(attr, node=instance, exists=True)
]

if instance_attrs:
attrs_per_instance[instance] = instance_attrs

if not attrs_per_instance:
# no instances with any frame related attributes
return

fields = ["data.{}".format(key) for key in attributes]
asset_doc = get_current_project_asset(fields=fields)
asset_data = asset_doc["data"]

for node, attrs in attrs_per_instance.items():
for attr in attrs:
plug = "{}.{}".format(node, attr)
value = asset_data[attr]
cmds.setAttr(plug, value)


def show_message(title, msg):
Expand Down
7 changes: 6 additions & 1 deletion openpype/hosts/maya/api/lib_rendersettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,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."""
Expand Down
3 changes: 2 additions & 1 deletion openpype/hosts/maya/api/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,8 @@ def on_task_changed():

with lib.suspended_refresh():
lib.set_context_settings()
lib.update_content_on_context_change()
lib.update_instances_frame_range()
lib.update_instances_asset_name()


def before_workfile_open():
Expand Down
11 changes: 10 additions & 1 deletion openpype/hosts/maya/api/workfile_template_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@
WorkfileBuildPlaceholderDialog,
)

from .lib import read, imprint, get_reference_node, get_main_window
from .lib import (
read,
imprint,
get_reference_node,
get_main_window,
update_instances_frame_range,
update_instances_asset_name,
)

PLACEHOLDER_SET = "PLACEHOLDERS_SET"

Expand Down Expand Up @@ -257,6 +264,8 @@ def post_placeholder_process(self, placeholder, failed):
cmds.sets(node, addElement=PLACEHOLDER_SET)
cmds.hide(node)
cmds.setAttr(node + ".hiddenInOutliner", True)
update_instances_frame_range()
update_instances_asset_name()

def delete_placeholder(self, placeholder):
"""Remove placeholder if building was successful"""
Expand Down
3 changes: 3 additions & 0 deletions openpype/settings/defaults/project_settings/maya.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,9 @@
"include_handles_default": false,
"per_task_type": []
},
"update_publishable_frame_range": {
"enabled": true
},
"scriptsmenu": {
"name": "OpenPype Tools",
"definition": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,24 @@
}
]
},
{
"type": "dict",
"collapsible": true,
"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 publishable instances will be updated when using the 'Reset Frame Range' functionality"
},
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
}
]
},
{
"type": "dict",
"key": "include_handles",
Expand Down

0 comments on commit 3960364

Please sign in to comment.