diff --git a/pype/nukestudio/__init__.py b/pype/nukestudio/__init__.py index 10053eb8bb..097f077e15 100644 --- a/pype/nukestudio/__init__.py +++ b/pype/nukestudio/__init__.py @@ -1,6 +1,5 @@ import os from pypeapp import Logger -import hiero from avalon import api as avalon from pyblish import api as pyblish @@ -17,7 +16,8 @@ from .menu import ( install as menu_install, _update_menu_task_label ) -from .tags import add_tags_from_presets + +from .events import register_hiero_events __all__ = [ # Workfiles API @@ -56,7 +56,8 @@ def install(config): Installing Nukestudio integration for avalon Args: - config (obj): avalon config module `pype` in our case, it is not used but required by avalon.api.install() + config (obj): avalon config module `pype` in our case, it is not + used but required by avalon.api.install() """ @@ -73,7 +74,8 @@ def install(config): # Disable all families except for the ones we explicitly want to see family_states = [ "write", - "review" + "review", + "plate" ] avalon.data["familiesStateDefault"] = False @@ -82,49 +84,8 @@ def install(config): # install menu menu_install() - # Workfiles. - launch_workfiles = os.environ.get("WORKFILES_STARTUP") - - if launch_workfiles: - hiero.core.events.registerInterest( - "kAfterNewProjectCreated", launch_workfiles_app - ) - - # Add tags on project load. - hiero.core.events.registerInterest( - "kAfterProjectLoad", add_tags - ) - - -def add_tags(event): - """ - Event for automatic tag creation after nukestudio start - - Args: - event (obj): required but unused - """ - - add_tags_from_presets() - - -def launch_workfiles_app(event): - """ - Event for launching workfiles after nukestudio start - - Args: - event (obj): required but unused - """ - from .lib import set_workfiles - - set_workfiles() - - # Closing the new project. - event.sender.close() - - # Deregister interest as its a one-time launch. - hiero.core.events.unregisterInterest( - "kAfterNewProjectCreated", launch_workfiles_app - ) + # register hiero events + register_hiero_events() def uninstall(): diff --git a/pype/nukestudio/events.py b/pype/nukestudio/events.py new file mode 100644 index 0000000000..822dc4db87 --- /dev/null +++ b/pype/nukestudio/events.py @@ -0,0 +1,107 @@ +import os +import hiero.core.events +from pypeapp import Logger +from .lib import sync_avalon_data_to_workfile, launch_workfiles_app +from .tags import add_tags_from_presets + +log = Logger().get_logger(__name__, "nukestudio") + + +def startupCompleted(event): + log.info("startup competed event...") + return + + +def shutDown(event): + log.info("shut down event...") + return + + +def beforeNewProjectCreated(event): + log.info("before new project created event...") + return + + +def afterNewProjectCreated(event): + log.info("after new project created event...") + # sync avalon data to project properities + sync_avalon_data_to_workfile() + + # add tags from preset + add_tags_from_presets() + + # Workfiles. + if int(os.environ.get("WORKFILES_STARTUP", "0")): + hiero.core.events.sendEvent("kStartWorkfiles", None) + # reset workfiles startup not to open any more in session + os.environ["WORKFILES_STARTUP"] = "0" + + +def beforeProjectLoad(event): + log.info("before project load event...") + return + + +def afterProjectLoad(event): + log.info("after project load event...") + # sync avalon data to project properities + sync_avalon_data_to_workfile() + + # add tags from preset + add_tags_from_presets() + + +def beforeProjectClosed(event): + log.info("before project closed event...") + return + + +def afterProjectClosed(event): + log.info("after project closed event...") + return + + +def beforeProjectSaved(event): + log.info("before project saved event...") + return + + +def afterProjectSaved(event): + log.info("after project saved event...") + return + + +def register_hiero_events(): + log.info( + "Registering events for: kBeforeNewProjectCreated, " + "kAfterNewProjectCreated, kBeforeProjectLoad, kAfterProjectLoad, " + "kBeforeProjectSave, kAfterProjectSave, kBeforeProjectClose, " + "kAfterProjectClose, kShutdown, kStartup" + ) + + # hiero.core.events.registerInterest( + # "kBeforeNewProjectCreated", beforeNewProjectCreated) + hiero.core.events.registerInterest( + "kAfterNewProjectCreated", afterNewProjectCreated) + + # hiero.core.events.registerInterest( + # "kBeforeProjectLoad", beforeProjectLoad) + hiero.core.events.registerInterest( + "kAfterProjectLoad", afterProjectLoad) + + # hiero.core.events.registerInterest( + # "kBeforeProjectSave", beforeProjectSaved) + # hiero.core.events.registerInterest( + # "kAfterProjectSave", afterProjectSaved) + # + # hiero.core.events.registerInterest( + # "kBeforeProjectClose", beforeProjectClosed) + # hiero.core.events.registerInterest( + # "kAfterProjectClose", afterProjectClosed) + # + # hiero.core.events.registerInterest("kShutdown", shutDown) + # hiero.core.events.registerInterest("kStartup", startupCompleted) + + # workfiles + hiero.core.events.registerEventType("kStartWorkfiles") + hiero.core.events.registerInterest("kStartWorkfiles", launch_workfiles_app) diff --git a/pype/nukestudio/lib.py b/pype/nukestudio/lib.py index 81b48f294d..c71e2cb999 100644 --- a/pype/nukestudio/lib.py +++ b/pype/nukestudio/lib.py @@ -25,19 +25,26 @@ def set_workfiles(): ''' Wrapping function for workfiles launcher ''' from avalon.tools import workfiles - # import session to get project dir - S = avalon.Session - active_project_root = os.path.normpath( - os.path.join(S['AVALON_PROJECTS'], S['AVALON_PROJECT']) - ) workdir = os.environ["AVALON_WORKDIR"] # show workfile gui workfiles.show(workdir) +def sync_avalon_data_to_workfile(): + # import session to get project dir + S = avalon.Session + active_project_root = os.path.normpath( + os.path.join(S['AVALON_PROJECTS'], S['AVALON_PROJECT']) + ) # getting project project = hiero.core.projects()[-1] + if "Tag Presets" in project.name(): + return + + log.debug("Synchronizing Pype metadata to project: {}".format( + project.name())) + # set project root with backward compatibility try: project.setProjectDirectory(active_project_root) @@ -48,7 +55,7 @@ def set_workfiles(): # get project data from avalon db project_data = pype.get_project()["data"] - log.info("project_data: {}".format(project_data)) + log.debug("project_data: {}".format(project_data)) # get format and fps property from avalon db on project width = project_data["resolutionWidth"] @@ -68,6 +75,17 @@ def set_workfiles(): log.info("Project property has been synchronised with Avalon db") +def launch_workfiles_app(event): + """ + Event for launching workfiles after nukestudio start + + Args: + event (obj): required but unused + """ + set_workfiles() + + + def reload_config(): """Attempt to reload pipeline at run-time. diff --git a/pype/nukestudio/tags.py b/pype/nukestudio/tags.py index 8ae88d731c..3a15f9f39e 100644 --- a/pype/nukestudio/tags.py +++ b/pype/nukestudio/tags.py @@ -52,7 +52,13 @@ def add_tags_from_presets(): """ Will create default tags from presets. """ + project = hiero.core.projects()[-1] + if "Tag Presets" in project.name(): + return + + log.debug("Setting default tags on project: {}".format(project.name())) + # get all presets presets = config.get_presets() @@ -77,7 +83,7 @@ def add_tags_from_presets(): # Get project assets. Currently Ftrack specific to differentiate between # asset builds and shots. - if int(os.getenv("TAG_ASSETBUILD_STARTUP", 0)) is 1: + if int(os.getenv("TAG_ASSETBUILD_STARTUP", 0)) == 1: nks_pres_tags["[AssetBuilds]"] = {} for asset in io.find({"type": "asset"}): if asset["data"]["entityType"] == "AssetBuild": @@ -150,3 +156,5 @@ def add_tags_from_presets(): # update only non hierarchy tags # because hierarchy could be edited update_tag(_t, _val) + + log.info("Default Tags were set...") diff --git a/pype/nukestudio/workio.py b/pype/nukestudio/workio.py index 3b6b3a56c9..1681d8a2ab 100644 --- a/pype/nukestudio/workio.py +++ b/pype/nukestudio/workio.py @@ -1,10 +1,11 @@ import os - import hiero - from avalon import api +from pypeapp import Logger +log = Logger().get_logger(__name__, "nukestudio") + def file_extensions(): return [".hrox"] @@ -12,20 +13,55 @@ def file_extensions(): def has_unsaved_changes(): # There are no methods for querying unsaved changes to a project, so # enforcing to always save. - return True + # but we could at least check if a current open script has a path + project = hiero.core.projects()[-1] + if project.path(): + return True + else: + return False def save_file(filepath): project = hiero.core.projects()[-1] - if project: + + # close `Untitled` project + if "Untitled" not in project.name(): + log.info("Saving project: `{}`".format(project.name())) project.saveAs(filepath) - else: + elif not project: + log.info("Creating new project...") project = hiero.core.newProject() project.saveAs(filepath) + else: + log.info("Dropping `Untitled` project...") + return def open_file(filepath): - hiero.core.openProject(filepath) + """Manually fire the kBeforeProjectLoad event in order to work around a bug in Hiero. + The Foundry has logged this bug as: + Bug 40413 - Python API - kBeforeProjectLoad event type is not triggered + when calling hiero.core.openProject() (only triggered through UI) + It exists in all versions of Hiero through (at least) v1.9v1b12. + + Once this bug is fixed, a version check will need to be added here in order to + prevent accidentally firing this event twice. The following commented-out code + is just an example, and will need to be updated when the bug is fixed to catch the + correct versions.""" + # if (hiero.core.env['VersionMajor'] < 1 or + # hiero.core.env['VersionMajor'] == 1 and hiero.core.env['VersionMinor'] < 10: + hiero.core.events.sendEvent("kBeforeProjectLoad", None) + + project = hiero.core.projects()[-1] + + # open project file + hiero.core.openProject(filepath.replace(os.path.sep, "/")) + + # close previous project + project.close() + + + return True