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

Dirmap in Nuke #2198

Merged
merged 10 commits into from
Nov 10, 2021
117 changes: 12 additions & 105 deletions openpype/hosts/maya/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from openpype.lib import any_outdated
import openpype.hosts.maya
from openpype.hosts.maya.lib import copy_workspace_mel
from openpype.lib.path_tools import HostDirmap
from . import menu, lib

log = logging.getLogger("openpype.hosts.maya")
Expand All @@ -30,7 +31,8 @@ def install():

project_settings = get_project_settings(os.getenv("AVALON_PROJECT"))
# process path mapping
process_dirmap(project_settings)
dirmap_processor = MayaDirmap("maya", project_settings)
dirmap_processor.process_dirmap()

pyblish.register_plugin_path(PUBLISH_PATH)
avalon.register_plugin_path(avalon.Loader, LOAD_PATH)
Expand Down Expand Up @@ -60,110 +62,6 @@ def install():
avalon.data["familiesStateToggled"] = ["imagesequence"]


def process_dirmap(project_settings):
# type: (dict) -> None
"""Go through all paths in Settings and set them using `dirmap`.

If artists has Site Sync enabled, take dirmap mapping directly from
Local Settings when artist is syncing workfile locally.

Args:
project_settings (dict): Settings for current project.

"""
local_mapping = _get_local_sync_dirmap(project_settings)
if not project_settings["maya"].get("maya-dirmap") and not local_mapping:
return

mapping = local_mapping or \
project_settings["maya"]["maya-dirmap"]["paths"] \
or {}
mapping_enabled = project_settings["maya"]["maya-dirmap"]["enabled"] \
or bool(local_mapping)

if not mapping or not mapping_enabled:
return
if mapping.get("source-path") and mapping_enabled is True:
log.info("Processing directory mapping ...")
cmds.dirmap(en=True)
for k, sp in enumerate(mapping["source-path"]):
try:
print("{} -> {}".format(sp, mapping["destination-path"][k]))
cmds.dirmap(m=(sp, mapping["destination-path"][k]))
cmds.dirmap(m=(mapping["destination-path"][k], sp))
except IndexError:
# missing corresponding destination path
log.error(("invalid dirmap mapping, missing corresponding"
" destination directory."))
break
except RuntimeError:
log.error("invalid path {} -> {}, mapping not registered".format(
sp, mapping["destination-path"][k]
))
continue


def _get_local_sync_dirmap(project_settings):
"""
Returns dirmap if synch to local project is enabled.

Only valid mapping is from roots of remote site to local site set in
Local Settings.

Args:
project_settings (dict)
Returns:
dict : { "source-path": [XXX], "destination-path": [YYYY]}
"""
import json
mapping = {}

if not project_settings["global"]["sync_server"]["enabled"]:
log.debug("Site Sync not enabled")
return mapping

from openpype.settings.lib import get_site_local_overrides
from openpype.modules import ModulesManager

manager = ModulesManager()
sync_module = manager.modules_by_name["sync_server"]

project_name = os.getenv("AVALON_PROJECT")
sync_settings = sync_module.get_sync_project_setting(
os.getenv("AVALON_PROJECT"), exclude_locals=False, cached=False)
log.debug(json.dumps(sync_settings, indent=4))

active_site = sync_module.get_local_normalized_site(
sync_module.get_active_site(project_name))
remote_site = sync_module.get_local_normalized_site(
sync_module.get_remote_site(project_name))
log.debug("active {} - remote {}".format(active_site, remote_site))

if active_site == "local" \
and project_name in sync_module.get_enabled_projects()\
and active_site != remote_site:
overrides = get_site_local_overrides(os.getenv("AVALON_PROJECT"),
active_site)
for root_name, value in overrides.items():
if os.path.isdir(value):
try:
mapping["destination-path"] = [value]
mapping["source-path"] = [sync_settings["sites"]\
[remote_site]\
["root"]\
[root_name]]
except IndexError:
# missing corresponding destination path
log.debug("overrides".format(overrides))
log.error(
("invalid dirmap mapping, missing corresponding"
" destination directory."))
break

log.debug("local sync mapping:: {}".format(mapping))
return mapping


def uninstall():
pyblish.deregister_plugin_path(PUBLISH_PATH)
avalon.deregister_plugin_path(avalon.Loader, LOAD_PATH)
Expand Down Expand Up @@ -326,3 +224,12 @@ def before_workfile_save(workfile_path):

workdir = os.path.dirname(workfile_path)
copy_workspace_mel(workdir)


class MayaDirmap(HostDirmap):
def on_enable_dirmap(self):
cmds.dirmap(en=True)

def dirmap_routine(self, source_path, destination_path):
cmds.dirmap(m=(source_path, destination_path))
cmds.dirmap(m=(destination_path, source_path))
61 changes: 61 additions & 0 deletions openpype/hosts/nuke/api/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
ApplicationManager
)
from openpype.tools.utils import host_tools
from openpype.lib.path_tools import HostDirmap
from openpype.settings import get_project_settings
from openpype.modules import ModulesManager

import nuke

from .utils import set_context_favorites
Expand Down Expand Up @@ -1795,3 +1799,60 @@ def recreate_instance(origin_node, avalon_data=None):
dn.setInput(0, new_node)

return new_node


class NukeDirmap(HostDirmap):
def __init__(self, host_name, project_settings, sync_module, file_name):
"""
Args:
host_name (str): Nuke
project_settings (dict): settings of current project
sync_module (SyncServerModule): to limit reinitialization
file_name (str): full path of referenced file from workfiles
"""
self.host_name = host_name
self.project_settings = project_settings
self.file_name = file_name
self.sync_module = sync_module

self._mapping = None # cache mapping

def on_enable_dirmap(self):
pass

def dirmap_routine(self, source_path, destination_path):
kalisp marked this conversation as resolved.
Show resolved Hide resolved
log.debug("{}: {}->{}".format(self.file_name,
source_path, destination_path))
self.file_name = self.file_name.replace(source_path, destination_path)


class DirmapCache:
"""Caching class to get settings and sync_module easily and only once."""
_project_settings = None
_sync_module = None

@classmethod
def project_settings(cls):
if cls._project_settings is None:
cls._project_settings = get_project_settings(
os.getenv("AVALON_PROJECT"))
return cls._project_settings

@classmethod
def sync_module(cls):
if cls._sync_module is None:
cls._sync_module = ModulesManager().modules_by_name["sync_server"]
return cls._sync_module


def dirmap_file_name_filter(file_name):
"""Nuke callback function with single full path argument.

Checks project settings for potential mapping from source to dest.
"""
dirmap_processor = NukeDirmap("nuke",
DirmapCache.project_settings(),
DirmapCache.sync_module(),
file_name)
dirmap_processor.process_dirmap()
return dirmap_processor.file_name
4 changes: 3 additions & 1 deletion openpype/hosts/nuke/startup/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

import nuke
from openpype.api import Logger
from openpype.hosts.nuke.api.lib import dirmap_file_name_filter

log = Logger().get_logger(__name__)


# fix ffmpeg settings on script
nuke.addOnScriptLoad(on_script_load)

Expand All @@ -20,4 +20,6 @@
# # set apply all workfile settings on script load and save
nuke.addOnScriptLoad(WorkfileSettings().set_context_settings)

nuke.addFilenameFilter(dirmap_file_name_filter)

log.info('Automatic syncing of write file knob to script version')
Loading