mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-25 21:32:15 +01:00
212 lines
5.9 KiB
Python
212 lines
5.9 KiB
Python
import os
|
|
import logging
|
|
import weakref
|
|
|
|
from maya import utils, cmds, mel
|
|
|
|
from avalon import api as avalon, pipeline, maya
|
|
from avalon.maya.pipeline import IS_HEADLESS
|
|
from pyblish import api as pyblish
|
|
|
|
from ..lib import (
|
|
update_task_from_path,
|
|
any_outdated
|
|
)
|
|
from . import menu
|
|
from . import lib
|
|
|
|
log = logging.getLogger("pype.maya")
|
|
|
|
PARENT_DIR = os.path.dirname(__file__)
|
|
PACKAGE_DIR = os.path.dirname(PARENT_DIR)
|
|
PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins")
|
|
|
|
PUBLISH_PATH = os.path.join(PLUGINS_DIR, "maya", "publish")
|
|
LOAD_PATH = os.path.join(PLUGINS_DIR, "maya", "load")
|
|
CREATE_PATH = os.path.join(PLUGINS_DIR, "maya", "create")
|
|
|
|
|
|
def install():
|
|
pyblish.register_plugin_path(PUBLISH_PATH)
|
|
avalon.register_plugin_path(avalon.Loader, LOAD_PATH)
|
|
avalon.register_plugin_path(avalon.Creator, CREATE_PATH)
|
|
|
|
menu.install()
|
|
|
|
log.info("Installing callbacks ... ")
|
|
avalon.on("init", on_init)
|
|
|
|
# Callbacks below are not required for headless mode, the `init` however
|
|
# is important to load referenced Alembics correctly at rendertime.
|
|
if IS_HEADLESS:
|
|
log.info("Running in headless mode, skipping Colorbleed Maya "
|
|
"save/open/new callback installation..")
|
|
return
|
|
|
|
avalon.on("save", on_save)
|
|
avalon.on("open", on_open)
|
|
avalon.on("new", on_new)
|
|
avalon.before("save", on_before_save)
|
|
|
|
log.info("Overriding existing event 'taskChanged'")
|
|
override_event("taskChanged", on_task_changed)
|
|
|
|
log.info("Setting default family states for loader..")
|
|
avalon.data["familiesStateToggled"] = ["imagesequence"]
|
|
|
|
|
|
def uninstall():
|
|
pyblish.deregister_plugin_path(PUBLISH_PATH)
|
|
avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH)
|
|
avalon.deregister_plugin_path(avalon.Creator, CREATE_PATH)
|
|
|
|
menu.uninstall()
|
|
|
|
|
|
def override_event(event, callback):
|
|
"""
|
|
Override existing event callback
|
|
Args:
|
|
event (str): name of the event
|
|
callback (function): callback to be triggered
|
|
|
|
Returns:
|
|
None
|
|
|
|
"""
|
|
|
|
ref = weakref.WeakSet()
|
|
ref.add(callback)
|
|
|
|
pipeline._registered_event_handlers[event] = ref
|
|
|
|
|
|
def on_init(_):
|
|
avalon.logger.info("Running callback on init..")
|
|
|
|
def safe_deferred(fn):
|
|
"""Execute deferred the function in a try-except"""
|
|
|
|
def _fn():
|
|
"""safely call in deferred callback"""
|
|
try:
|
|
fn()
|
|
except Exception as exc:
|
|
print(exc)
|
|
|
|
try:
|
|
utils.executeDeferred(_fn)
|
|
except Exception as exc:
|
|
print(exc)
|
|
|
|
# Force load Alembic so referenced alembics
|
|
# work correctly on scene open
|
|
cmds.loadPlugin("AbcImport", quiet=True)
|
|
cmds.loadPlugin("AbcExport", quiet=True)
|
|
|
|
# Force load objExport plug-in (requested by artists)
|
|
cmds.loadPlugin("objExport", quiet=True)
|
|
|
|
# Force load objExport plug-in (requested by artists)
|
|
cmds.loadPlugin("spore", quiet=True)
|
|
|
|
from .customize import (
|
|
override_component_mask_commands,
|
|
override_toolbox_ui
|
|
)
|
|
safe_deferred(override_component_mask_commands)
|
|
|
|
if not IS_HEADLESS:
|
|
safe_deferred(override_toolbox_ui)
|
|
|
|
|
|
def on_before_save(return_code, _):
|
|
"""Run validation for scene's FPS prior to saving"""
|
|
return lib.validate_fps()
|
|
|
|
|
|
def on_save(_):
|
|
"""Automatically add IDs to new nodes
|
|
|
|
Any transform of a mesh, without an existing ID, is given one
|
|
automatically on file save.
|
|
"""
|
|
|
|
avalon.logger.info("Running callback on save..")
|
|
|
|
# # Update current task for the current scene
|
|
# update_task_from_path(cmds.file(query=True, sceneName=True))
|
|
|
|
# Generate ids of the current context on nodes in the scene
|
|
nodes = lib.get_id_required_nodes(referenced_nodes=False)
|
|
for node, new_id in lib.generate_ids(nodes):
|
|
lib.set_id(node, new_id, overwrite=False)
|
|
|
|
|
|
def on_open(_):
|
|
"""On scene open let's assume the containers have changed."""
|
|
|
|
from avalon.vendor.Qt import QtWidgets
|
|
from ..widgets import popup
|
|
|
|
# # Update current task for the current scene
|
|
# update_task_from_path(cmds.file(query=True, sceneName=True))
|
|
|
|
# Validate FPS after update_task_from_path to
|
|
# ensure it is using correct FPS for the asset
|
|
lib.validate_fps()
|
|
|
|
if any_outdated():
|
|
log.warning("Scene has outdated content.")
|
|
|
|
# Find maya main window
|
|
top_level_widgets = {w.objectName(): w for w in
|
|
QtWidgets.QApplication.topLevelWidgets()}
|
|
parent = top_level_widgets.get("MayaWindow", None)
|
|
|
|
if parent is None:
|
|
log.info("Skipping outdated content pop-up "
|
|
"because Maya window can't be found.")
|
|
else:
|
|
|
|
# Show outdated pop-up
|
|
def _on_show_inventory():
|
|
import avalon.tools.cbsceneinventory as tool
|
|
tool.show(parent=parent)
|
|
|
|
dialog = popup.Popup(parent=parent)
|
|
dialog.setWindowTitle("Maya scene has outdated content")
|
|
dialog.setMessage("There are outdated containers in "
|
|
"your Maya scene.")
|
|
dialog.on_show.connect(_on_show_inventory)
|
|
dialog.show()
|
|
|
|
|
|
def on_new(_):
|
|
"""Set project resolution and fps when create a new file"""
|
|
avalon.logger.info("Running callback on new..")
|
|
with maya.suspended_refresh():
|
|
lib.set_context_settings()
|
|
|
|
|
|
def on_task_changed(*args):
|
|
"""Wrapped function of app initialize and maya's on task changed"""
|
|
|
|
# Inputs (from the switched session and running app)
|
|
session = avalon.Session.copy()
|
|
app_name = os.environ["AVALON_APP_NAME"]
|
|
|
|
# Find the application definition
|
|
app_definition = pipeline.lib.get_application(app_name)
|
|
|
|
App = type("app_%s" % app_name,
|
|
(avalon.Application,),
|
|
{"config": app_definition.copy()})
|
|
|
|
# Initialize within the new session's environment
|
|
app = App()
|
|
env = app.environ(session)
|
|
app.initialize(env)
|
|
|
|
# Run
|
|
maya.pipeline._on_task_changed()
|